How to change properties of a QML Object during runtime in C++?

后端 未结 1 1672
陌清茗
陌清茗 2021-01-23 20:39

I want to change the text of a QML Object during runtime.

I tried it as following, but the text just stays empty.

This is the BackEnd class:

cla         


        
相关标签:
1条回答
  • 2021-01-23 20:59

    You have the following errors:

    • As you point you have created an instance of Backend in one thread, and another instance in QML, so the modification of the state of one instance does not modify the other instance. In these cases where you want to have an object in C++ and QML it is better to create a context-property with setContextProperty().

    • QML only accepts objects that live in the main thread so the Backend object can not be created in another thread, one possibility is that you create another object that lives in the secondary thread and transmits the data to the main thread by signals, another possibility is to use QThread that accepts the creation of signals and connect it to the Backend object.

    • The properties that you want to do binding in QML must be notifiable through a signal.

    Considering the above, an example is the following:

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题