如何在C++运行时更改QML对象的属性
How to change properties of a QML Object during runtime in C++?
我想在运行时更改QML对象的文本。
我按如下所示进行了尝试,但文本始终为空。
这是后端类:
class BackEnd : public QObject {
Q_OBJECT
Q_PROPERTY(QString userFieldText READ userFieldText WRITE setUserFieldText)
public:
explicit BackEnd(QObject *parent = nullptr);
QString userFieldText();
void setUserFieldText(QString &username);
private:
QString _userFieldText;
};
在qml文件中,我包括window.backend,创建一个新的后端实例,并尝试访问等值
BackEnd {
id: backend
}
Text {
...
text: backend.userFieldText
}
我是这样注册的。
qmlRegisterType<BackEnd>("window.backend", 0, 1, "BackEnd");
在一个我想更改对象的单独线程中,我创建了一个BackEnd类的实例并调用setter函数。
BackEnd backend;
QString user("set by backend");
backend.setUserFieldText(user);
编译工作,它运行,但不会改变任何东西。我已经试着把它放在QML代码中的计时器中,并每秒更新一次,但似乎什么都不起作用。
您有以下错误:
-
正如您所指出的,您已经在一个线程中创建了
Backend
的实例,并在QML中创建了另一个实例,因此对一个实例的状态的修改不会修改其他实例。在这些情况下,如果您希望在C++和QML中有一个对象,最好使用setContextProperty()
创建一个上下文属性。 -
QML只接受存在于主线程中的对象,因此后端对象不能在另一个线程中创建,一种可能性是您创建了另一个存在于次线程中并通过信号将数据传输到主线程的对象,另一种可能是使用接受信号创建的
QThread
并将其连接到Backend
对象。 -
要在QML中进行绑定的属性必须通过信号进行通知。
考虑到以上情况,示例如下:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QThread>
class BackEnd : public QObject {
Q_OBJECT
Q_PROPERTY(QString userFieldText READ userFieldText WRITE setUserFieldText NOTIFY userFieldTextChanged)
public:
explicit BackEnd(QObject *parent = nullptr):
QObject(parent){}
QString userFieldText() const {
return _userFieldText;
}
void setUserFieldText(const QString &username){
if(userFieldText() == username) return;
_userFieldText = username;
emit userFieldTextChanged();
}
signals:
void userFieldTextChanged();
private:
QString _userFieldText;
};
class WorkerThread: public QThread
{
Q_OBJECT
public:
using QThread::QThread;
~WorkerThread() override {
requestInterruption();
quit();
wait();
}
signals:
void textChanged(const QString &);
protected:
void run() override{
while (!isInterruptionRequested()) {
emit textChanged(QString("set by backend: %1 ").arg(counter));
QThread::msleep(100);
counter++;
}
}
private:
int counter = 0;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
BackEnd backend;
WorkerThread thread;
QObject::connect(&thread, &WorkerThread::textChanged, &backend, &BackEnd::setUserFieldText);
thread.start();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("backend", &backend);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Text {
anchors.centerIn: parent
text: backend.userFieldText
}
}
相关文章:
- QML 对象的销毁顺序
- 使用 createComponent 动态创建 QML 对象
- 可以在 QObject::connect() C++中连接 QML 对象现有信号?
- 如何删除 QML 对象
- 销毁 qml 对象后的信号槽连接
- 将 QObject 指针从 QML 对象传递到C++
- 使用C 访问QT / QML对象
- 如何使用 API 获取 QML 对象的 id 属性C++
- 如何在C++运行时更改QML对象的属性
- 与C++代码中的 qml 对象交互
- 如何从C++访问嵌套的 QML 对象
- 使用cpp代码从加载的qml访问qml对象
- 从C++访问 QML 对象
- 如何从C++调用 QML 对象的方法
- 从具有指定属性的C++创建 QML 对象
- 在现有 C++ QT 项目中实例化 QML 对象
- QML 对象属性的部分序列化
- 区分C++中QML对象的类类型
- 使用c++设置qml对象的属性
- 将qml对象添加到QGraphicsScene