QML – 从C++调用QML方法,控制台输出看起来正确但失败

huangapple go评论61阅读模式
英文:

QML - invoking QML methods from C++, console output looks correct but failed

问题

我试图从Qt C++代码中更新一个MapQuickItem,调试控制台输出看起来正常,但是GUI上的地图没有更新。我在QML中有一个MouseArea onClicked来测试相同的QML方法,它工作得很完美,新项目已添加到地图并重新定位。可能出了什么问题?

以下是C++代码:

mainwindow.cpp:

QQmlEngine engine;
QQmlComponent component(&engine, "map.qml");
QObject *mapObject = component.create();
QVariant arg1 = 1;
QVariant lat = 10.123465;
QVariant lon = 10.123456;
QVariant bearing = 50;
QMetaObject::invokeMethod(mapObject, "updateDrone",
                                      Q_RETURN_ARG(QVariant, reVal),
                                      Q_ARG(QVariant, arg1),
                                      Q_ARG(QVariant, lat),
                                      Q_ARG(QVariant, lon),
                                      Q_ARG(QVariant, bearing));

map.qml:

Rectangle {
    // ... (中间部分未提供)
    function updateDrone(droneNum, currLat, currLon, bearing) {
        console.log("updateDrone called");

        if (drone !== undefined)
            mapView.removeMapItem(drone);
        addDrone(droneNum, currLat, currLon, bearing);

        if (autoUpdate && centerDrone === droneNum) {

            console.log("panning");

            mapView.pan(centerLat - currLat, centerLon - currLon);

            centerLat = currLat;
            centerLon = currLon;
        }
    }

    function addDrone(droneNum, currLat, currLon, bearing) {
        console.log("addDrone called")

        drone = droneMaker.createObject(window,
                    {coordinate: QtPositioning.coordinate(currLat, currLon),
                        bearing: bearing});
        mapView.addMapItem(drone)

        console.log(drone.bearing)
        console.log(drone.coordinate)
        console.log("drone added")
    }

    // ... (中间部分未提供)
}

从C++调用该方法时的控制台输出:
在此处输入图片描述

从鼠标单击调用该方法时的控制台输出:
在此处输入图片描述

英文:

I was trying to updating an MapQuickItem from Qt C++ code, the debugging console output looks fine, but the map on the GUI is not updated. I have a MouseArea onClicked in QML to test the same QML methods and it works perfectly, new item was added to the map and recenter. What could went wrong?

Here's the C++ code:

mainwindow.cpp:

QQmlEngine engine;
QQmlComponent component(&engine, "map.qml");
QObject *mapObject = component.create();
QVariant arg1 = 1;
QVariant lat = 10.123465;
QVariant lon = 10.123456;
QVariant int = 50;
QMetaObject::invokeMethod(mapObject, "updateDrone",
                                      Q_RETURN_ARG(QVariant, reVal),
                                      Q_ARG(QVariant, arg1),
                                      Q_ARG(QVariant, lat),
                                      Q_ARG(QVariant, lon),
                                      Q_ARG(QVariant, bearing));

map.qml:

Rectangle {
    id: window
    property Component droneMaker: droneMarker
    property var drone: undefined
    property double centerLat: 32.848168
    property double centerLon: -111.487827

    Plugin {
        id: mapPlugin
        name: "osm"
    }

    Map {
        id: mapView
        anchors.fill: parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(centerLat, centerLon)
        zoomLevel: 13
    }

    function updateDrone(droneNum: int, currLat: double, currLon: double, bearing: int) {
        console.log("updateDrone called");

        if (drone !== undefined)
            mapView.removeMapItem(drone);
        addDrone(droneNum, currLat, currLon, bearing);

        if (autoUpdate && centerDrone === droneNum) {

            console.log("panning");

            mapView.pan(centerLat - currLat, centerLon - currLon);

            centerLat = currLat;
            centerLon = currLon;
        }
    }

    function addDrone(droneNum: int, currLat: double, currLon: double, bearing: int) {
        console.log("addDrone called")

        drone = droneMaker.createObject(window,
                    {coordinate: QtPositioning.coordinate(currLat, currLon),
                        bearing: bearing});
        mapView.addMapItem(drone)

        console.log(drone.bearing)
        console.log(drone.coordinate)
        console.log("drone added")
    }

    Component {
        id: droneMarker
        MapQuickItem {
            id: drone
            property int bearing: 0

            anchorPoint.x: droneImage.width/2
            anchorPoint.y: droneImage.height/2
            coordinate: position

            sourceItem: Image {
                id: droneImage
                source: "drone.png"
            }
        }
    }

    MouseArea {
        anchors.fill: parent

        onClicked:  {
            var coordinate = mapView.toCoordinate(Qt.point(mouse.x,mouse.y))
            console.log("clicked")
            updateDrone(1, coordinate.latitude, coordinate.longitude, 45);
        }
    }

}

Here is the console output when calling the method from C++:
enter image description here

Here is the console output when calling the method from mouse click:
enter image description here

答案1

得分: 0

原来我先通过引擎加载了我的QML,然后再通过快速小部件加载了一遍。
我删除了引擎代码,使用了这个替代,现在一切正常了:
#include <QQuickItem>
#include <QQuickView>
ui -> map -> setSource(QUrl(QStringLiteral("qrc:/map.qml")));
ui -> map -> show();
mapObject = ui -> map -> rootObject();
英文:

Turns out I have loaded my QML through the engine first, then through quickwidget again.

I deleted the engine code and used this to instead and it's all working now:

#include <QQuickItem>
#include <QQuickView>

ui -> map -> setSource(QUrl(QStringLiteral("qrc:/map.qml")));
ui -> map -> show();
mapObject = ui -> map -> rootObject();

huangapple
  • 本文由 发表于 2023年3月23日 12:12:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75819190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定