QThread and Qtimer not work together



  • Hi all,

    below is my test code which further i am goin to use in my main project.
    issue i am having at the moment is my QTimer unable to execute respective slot if i creat one thread from same class.

    tweak : if i comment out thread part everything works fine using QTimer only.
    but i need both work simultaneously.

    i am not sure my approach is safe or not but still trying to learn it out.
    Pls give me feedback on correct way to work all smooth.

    platform : ubuntu 14.04, Qt 4.8 desktop - embedded application.

    // test.h
    
    class test: public QObject{
    
        Q_OBJECT
    
    public :
        QThread *io_threadObj = new QThread(this);
        QTimer *ioTimer = new QTimer;
    
    public slots:
           Q_INVOKABLE void requestFunction();
           Q_INVOKABLE void vCheckSerialData(void);
    };
    
    // test.cpp
    
    void test::requestFunction()
    {
        qDebug() << "called from timer.";
    }
    
    
    void test :: vCheckSerialData()
    {
        while(1) {
    
            qDebug() << "called from thread.";
            sleep(2);
        }
    
    }
    
    // main.cpp
    
    #include <QApplication>
    #include "qmlapplicationviewer.h"
    
    
    #include "test.h"
    
    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
        QScopedPointer<QApplication> app(createApplication(argc, argv));
    
        QmlApplicationViewer viewer;
        viewer.addImportPath(QLatin1String("modules"));
        viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
        viewer.setMainQmlFile(QLatin1String("qml/thread_timer/main.qml"));
        viewer.showExpanded();
    
    
        test *testObj= new test;
    
        testObj->ioTimer->setInterval(2000);
        bool conctStat=QObject::connect(testObj->ioTimer, SIGNAL(timeout()), testObj, SLOT(requestFunction()));
    
        qDebug() <<"conctStat ::" <<conctStat;
    
    //  thread part
        testObj->moveToThread(testObj->io_threadObj);
        QObject::connect(testObj->io_threadObj,SIGNAL(started()),testObj, SLOT(vCheckSerialData()));
    
        testObj->ioTimer->start();
        testObj->io_threadObj->start();
    
        return app->exec();
    }
    
    // output i am getting :
    
    Qml debugging is enabled. Only use this in a safe environment!
    conctStat :: true 
    called from thread. 
    called from thread. 
    called from thread. 
    
    // expected output
    
    Qml debugging is enabled. Only use this in a safe environment!
    conctStat :: true 
    called from thread. 
    called from timer.
    called from thread. 
    called from timer.
    called from thread. 
    called from timer.
    


  • While this code is a mess the problem is here: bool conctStat=QObject::connect(testObj->ioTimer, SIGNAL(timeout()), testObj, SLOT(requestFunction()));

    testObj->ioTimer is not a child of testObj so it will remain in the main thread when you call testObj->moveToThread(testObj->io_threadObj);. That connection is hence a queued connection so the slot will be evaluated in the receiver's thread. Since you are blocking the event loop of the receiving thread with an infinite loop you get the output you posted.

    I suggest a read of https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/



  • @VRonin thanx for ur repl.
    i did go through the link you mention. still bit confused with concept.
    at the moment i fix it with creating one more object.
    i.e. one object for timer and one object for thread process.

    this approach is also not good but help me t move on.
    i want to achieve expected output using same object.

    note : i keep this thread open as my doubt is not clear yet, looking for better solution.

        test *testObj= new test;
        test *testObj2= new test;
    
        QThread *io_threadObj = new QThread();
    
        QTimer *ioTimer = new QTimer;
        ioTimer->setInterval(2000);
        bool conctStat=QObject::connect(ioTimer, SIGNAL(timeout()), testObj, SLOT(requestFunction()));
        ioTimer->start();
    
    
    // serial io thread
        testObj2->moveToThread(io_threadObj);
        QObject::connect(io_threadObj,SIGNAL(started()),testObj2, SLOT(vCheckSerialData()));
        io_threadObj->start();```


  • Be careful

    no leaks


Log in to reply
 

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