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 oftestObj
so it will remain in the main thread when you calltestObj->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();```