从 C++ 更新 QML 对象的正确方法?

Proper way to update QML object from C++?

我找到了这个 How to modify a QML Text from C++ 但我听说从 C++ 更新 QML 对象不是线程安全的

这样做的正确方法是什么?

我认为最简单的例子(一个文本小部件)足以让我理解。

注意:我没有指出这段代码不是线程安全的,我已经指出你在中的代码不是线程安全的,因为您从与其所属线程不同的线程修改 GUI。

我已经指出 this answer 的代码是危险的,不推荐,因为 QML 元素的生命周期不由开发人员管理,QML 引擎可以在不通知我们的情况下删除它们,因此我建议创建 QObject 以在 C++ 和 QML 之间获取或发送信息

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

class Helper: public QObject{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
    QString m_text;
public:
    using QObject::QObject;
    QString text() const{
        return m_text;
    }
public slots:
    void setText(QString text){
        if (m_text == text)
            return;
        m_text = text;
        emit textChanged(m_text);
    }
signals:
    void textChanged(QString text);
};

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

    QGuiApplication app(argc, argv);

    Helper helper;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("helper", &helper);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    helper.setText("Change you text here...");

    return app.exec();
}
#include "main.moc"

main.qml

Text {
    id: text1
    color: "red"
    <b>text: helper.text</b>
    font.pixelSize: 12
}

Text {
    id: text1
    color: "red"
    text: "This text should change..."
    font.pixelSize: 12
}
<b>Connections{
    target: helper
    onTextChanged: text1.text = text
}</b>