如何从 c++ 更改 QML 项的属性

How to change property of QML item from c++

本文关键字:属性 QML 更改 c++      更新时间:2023-10-16

我正在用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;
}
}

地图.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
}
}

通过这样做:

// 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();
}