如何从C ++更改QML项目的属性

时间:2019-04-25 08:00:17

标签: c++ qt qml

我正在用C ++写一个小的QT(5.12)应用程序,它将每秒移动一次QMap的中心。我正在尝试更新坐标,以便中心会刷新,但是在调试它之后,它始终保持不变(原始值)。这是我第一次尝试使用QML,因此我正在帮助自己解决波纹管问题,但显然我没有做正确的事情。

https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html

计时器每秒调用一次更新功能

#include <QQmlEngine>
#include <QQmlComponent>

void MainWindow::UpdateCoordinates()
{
    float LATDEGM = (60 * 1853.181);
    float DEG2RAD = (PI / 180.0);

    QString speedData = ui->sboxSpeed->text();
    bool ok;
    AirSpeed = speedData.toInt(&ok);
    AirCourse = (AirCourse + 360) % 360;

    Dx = AirSpeed * sin((float)AirCourse * DEG2RAD);
    Dy = AirSpeed * cos((float)AirCourse * DEG2RAD);

    QString dat = ui->txtLatitude->text();
    Lat = dat.toDouble();
    QString dat2 = ui->txtLongtitude->text();
    Lon = dat2.toDouble();

    Dx /= 3.6;
    Dy /= 3.6;

    Lat += Dy / LATDEGM;
    Lon += Dx / (LATDEGM * cos(Lat * DEG2RAD));

    ui->txtLatitude->setText(QString::number(Lat));
    ui->txtLongtitude->setText(QString::number(Lon));

    // Using QQmlComponent
    QQmlEngine engine;
    QQmlComponent component(&engine,QUrl(QStringLiteral("qrc:/Map.qml")));
    QObject *object = component.create();
    QObject *map = object->children().at(1);

    if (map)
    {
        map->setProperty("newLatitude", Lat);
        map->setProperty("newLongitude", Lon);
        std::cout << "Property value:" << map->property("latitude").toDouble() << std::endl;
        std::cout << "Property value:" << map->property("longitude").toDouble() << std::endl;
    }
}

Map.qml

import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6

Item{
    id: itemControl
    width: 512
    height: 512
    visible: true

    property alias newLongitude : map.longitude;
    property alias newLatitude : map.latitude;

    Plugin {
        id: mapPlugin
        name: "esri"
    }

    Map {
        id: map
        anchors.fill: parent
        maximumZoomLevel: 15
        minimumZoomLevel: 15
        width: 512
        height: 512
        plugin: mapPlugin
        center {
            property real latitude: 45.5082047
            property real longitude: 13.5757492
        }
        zoomLevel: 14
    }
}

1 个答案:

答案 0 :(得分:3)

这样做:

    // Using QQuickView
    QQmlEngine engine;
    QQmlComponent component(&engine,QUrl(QStringLiteral("qrc:/Map.qml")));
    QObject *object = component.create();
    QObject *map = object->children().at(1);

您正在创建视图的新本地实例。因此,您无需修改​​当前视图。

最简单的将数据发送到视图的方法是使用信号/插槽。或者,您可以将组件上的指针传递到MainWindow

例如:

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    property int foobar: -1
    Label {
        text: foobar
    }
}
class Worker: public QObject
{
public:
    Worker(QObject* map): QObject(),
        map(map)
    {
        startTimer(500);
    }

    void timerEvent(QTimerEvent* ev)
    {
        static int i = 0;
        ++i;
        map->setProperty("foobar", i);
    }
private:
    QObject* map;
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QObject* obj = engine.rootObjects().first();

    Worker* worker = new Worker(obj);

    return app.exec();
}

带有信号/插槽的简单示例(在类Worker不必了解内部组件时很有用)


ApplicationWindow {
    visible: true
    width: 640
    height: 480

    function update(value) {
        label.text = value;
    }

    Label {
        id: label
        text: "None"
    }
}
class Worker: public QObject
{
    Q_OBJECT
public:
    Worker(): QObject()
    {
        startTimer(500);
    }

    void timerEvent(QTimerEvent* ev)
    {
        static int i = 0;
        ++i;
        emit update(i);
    }

signals:
    void update(QVariant newValue);
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QObject* obj = engine.rootObjects().first();

    Worker* worker = new Worker();

    QObject::connect(worker, SIGNAL(update(QVariant)), obj, SLOT(update(QVariant)));
    return app.exec();
}