QThread, QML



  • Hello,
    I don't have any problem here, but it is just to have opinions about my method if I am doing it in the correct way.
    The idea is to build an application with QML, and use Thread for complex operations.
    The main problem is : QML Object can't be in another thread than QMLApplicationEngine.
    So, I am using one "WorkerInterface" which own the QThread.
    Maybe in this case, it should be better to use QConcurrent ?

    It is my code :
    "main.qml", simple, just a button

    import QtQuick 2.5
    import QtQuick.Controls 1.4
    import Workers 1.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        SystemPalette {
            id: pal
            colorGroup: SystemPalette.Active
        }
    
        Worker {
            id: worker;
        }
    
        Button {
            id: button
            text: qsTr("Process")
            anchors.centerIn: parent
    
            onClicked: worker.process();
        }
    
        Text {
            text: worker.data
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: button.bottom
            anchors.topMargin: 20
        }
    }
    

    Main.cpp

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QQmlComponent>
    #include "worker.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        qmlRegisterType<WorkerInterface>("Workers", 1, 0, "Worker");
    
        QQmlApplicationEngine engine;
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        qDebug() << "Main thread : " << QThread::currentThreadId();
    
        return app.exec();
    }
    

    And the worker.h

    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    #include <QDebug>
    #include <QThread>
    
    class Worker: public QObject {
        Q_OBJECT
    public:
        Worker(QString &data) : mData(data) {}
    
    public slots:
        void process() {
            qDebug() << "Process's Thread : " << QThread::currentThreadId();
            mData += "process\n";
    
            emit processFinished();
        }
    
    signals:
        void processFinished();
    
    private:
        QString &mData;
    };
    
    class WorkerInterface : public QObject {
        Q_OBJECT
        Q_PROPERTY(QString data READ getData NOTIFY dataChanged)
    public:
        WorkerInterface() : mWorker(mData) {
            mWorker.moveToThread(&mThread);
            connect(this, &WorkerInterface::process, &mWorker, &Worker::process);
            connect(&mWorker, &Worker::processFinished, [this]{
                qDebug() << "ProcessFinished in  : " << QThread::currentThreadId();
                emit dataChanged();
            });
    
            mThread.start();
        }
    
        QString getData() const {
            return mData;
        }
    
        ~WorkerInterface() {
            mThread.exit();
            mThread.wait();
        }
    
    signals:
        void dataChanged();
        void process();
    
    private:
        QThread mThread;
        QString mData;
        Worker mWorker;
    };
    
    #endif // WORKER_H
    
    

    Thanks for your advices :).


  • Qt Champions 2016

    I think QRunnable will be a better choice than QThread.



  • Hello,
    I am not very convenient with QRunnable ,so I would rather use QConcurrent than QRunnable ^^.
    But this example is just to ask if my way to use thread is the good one, because in my future applications I will have to use a real Object :p.
    Thanks for your answer :).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.