Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Access QML click event from C++ worker thread



  • Hi
    I want to access a QML object click in a C++ class that it is in a separate thread (using moveToThread() ). The class behaves strange when I use it in QML side. My timer and a QVector variable (CAList) disturbed!
    Is there a conflict between QML type and thread?
    Here is my Code:

    // in main.cpp
    qmlRegisterType<FrameProcessor>("frameProcessor", 1, 0, "FrameProcessor");
    
    // in mainwindow.h
        QThread *workerThread_2;
        FrameProcessor *workerObject_2 = new FrameProcessor();
    
    // in mainwindow.cpp
        workerThread_2 = new QThread();
        workerObject_2->moveToThread(workerThread_2);
    
    // in FrameProcessor.h
    public slots:
        void getClicked(QString icao);
    
    //
    // frameprocessor.cpp
    void FrameProcessor::getClickedICAO(QString text)
    {
        qDebug()  << text;
    }
    
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()),
                  this, SLOT(MyTimerSlot()));
        timer->start(1000);
    
    void FrameProcessor::MyTimerSlot()
    {
        QVector<double> data;
        int validNumbers = 0;
    
        qDebug() << CAList;
    
        if (List.size() > 0)
        {
            for(int i = 0; i < List.size(); i++)
            {
                if(List[i].Head >= 0)
                {
                    data.append(List[i].Speed);
    
                    validNumbers++;
                }
            }
        }
        else
        {
            validNumbers = 0;
        }
    
        emit sendData(data, CAList, selectedCA, validNumbers * 8);
    }
    

    The CAList became clear!
    when I comment emit it works!!!
    and also when comment:

    FrameProcessor
     {
         id:plane
    }
    

    in QML file.
    I tried to explain my problem, sorry if it's vague.



  • hi,
    I solved the problem, instead of using qmlRegisterType, I used setContextProperty for my widget that uses qml map (I didn't know this tip). so in the qml root I have access to my C++ class and use its methods.
    Thanks @isdsi for your reply.



  • If the content you want to process needs to be done in a class defined as a qml type, you can try workerscript.
    https://doc.qt.io/qt-5/qtquick-threading-example.html#workerscript

    Otherwise, if it is a structure that can be run on a separate thread and then passed to the qml type, create a separate c ++ class in the worker thread and then emit the qml type as a c ++ class.
    https://doc.qt.io/qt-5/threads-technologies.html

    Be careful when using moveToThread. You need to figure out the relationship between QObject and QThread. QObject recognizes the thread as its owner when it is created in the thread in progress. Afterwards, if moveToThread is executed, the QThread of the argument runs and executes an event action.
    And when the thread terminates, the QObjects playing on the thread will not work.



  • hi,
    I solved the problem, instead of using qmlRegisterType, I used setContextProperty for my widget that uses qml map (I didn't know this tip). so in the qml root I have access to my C++ class and use its methods.
    Thanks @isdsi for your reply.


Log in to reply