我想在运行时更改 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 实例并尝试访问如下值
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 只接受存在于主线程中的对象,因此不能在另一个线程中创建 Backend 对象,一种可能是您创建另一个存在于辅助线程中的对象并通过信号将数据传输到主线程,另一种可能性是使用QThread
接受信号的创建并将其连接到Backend
object.
您想要在 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
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)