QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait()
Hi guys!
I have the following problem:
1. I want get thread doing some work and update the label in the main thread every second.
2. I got it working subclassing QThread bu according to some sources it is not a good way.
3. I decided to subclass a QObject (MyObject) with internal QTimer* _myTimer, and doWork() function with an internal loop, This object is after construction moved to newly created QThread* _thread.
My problem is that _myTimer's timeout() signal which is connected to tick() slot of the _myObject, is not executed after _thread->start(). tick() is executed only after doing _thread->wait(). Both the tick() slot and myTimer exist in the myThread so i do not know what is the problem. It seems like there is no event loop in myThread.
Here is my code:
Code:
{
Q_OBJECT
public:
public slots:
void tick();
void doWork();
private:
};
void MyObject::doWork()
{
_myTimer->setInterval(1000);
connect(_myTimer, SIGNAL(timeout()), this, SLOT(tick())/*,Qt::DirectConnection*/);
_myTimer->start()
qDebug
() <<
QThread::currentThreadId() <<
"doWork()";
while(..)
{
...
}
}
void MyObject::tick()
{
emit tickSignalToGUI(..);
qDebug
() <<
QThread::currentThreadId() <<
"tick()";
}
// and somewhere in GUI thread
(...)
_myObject = new MyObject(); /
_myObject->moveToThread(_thread);
_thread->start();
// _myObject->doWork(); //this blocks execution
qDebug
() <<
QThread::currentThreadId() <<
"GUI thread";
(...)
Any ideas what is wrong with this approach?
best regards,
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
what you are doing is even worse than subclassing QThread (not that subclassing QThread is bad)
You are blocking the main thread with the while(...) loop in MyObject.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
Quote:
Originally Posted by
amleto
what you are doing is even worse than subclassing QThread (not that subclassing QThread is bad)
You are blocking the main thread with the while(...) loop in MyObject.
Are you sure? As myObject with its while loop is moved to another thread it seems to run concurently to main thread. At least the GUI stays responsive and processes all the events.
best regads.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
well, now that you have changed it to QMetaObject::invokeMethod with your edit it should be a lot better... :rolleyes:
Now you're just blocking the other thread with that while(...)
You know it would be handy if you didn't hide code that is directly relevant to your question. :rolleyes:
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
sorry for that.. your footnote really make sense;)
Do you have any idea why the signals from timer are not processed during the doWork()? They start to be processed after i try to finish _myThread with _mythread->wait(). :/
I cant find any good way to let the timer work in a separate thread.:(
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
how many times do you think I shall say that your while(...) is* blocking before you will think that might be the cause?
*guessing since you are still hiding that code...
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
One with some additional comment would be enough.
So how to avoid this devilish while(..) and still do some processing loop that can coexist with the timer in harmony?
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
use signals and slots. not while(true) or equivalent
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
My doWork() is processing some number of items. It should process this data unless user presses Pause button or Stop button. I initially made a QThread subclass which in run() had while(true) (i guess that this is not a bad practice in thread?) and some exit conditions checking flags set by signals from GUI. As "this->moveToThread(this)" trick is not a good thing to do i have rebuild my QThread subclass to QObject subclass.
How would you rebuild the while(true){} processing loop to fit "QObject moved to QThread" approach?
Best regards.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
How do you expect me to say how you can refactor your while loop when you have given no information about what it actually does and where the input comes from :mad::mad::confused::rolleyes:
I give up. Just use this.
http://doc.qt.io/qt-4.8/qcoreapplication.html#processEvents
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
If you suggest to use:
Code:
doWork()
{
(...)
while(true)
{
(...)
}
it does not solve the problem.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
read my sig
All your timer does is send signal. you can put your timer anywhere. Why does it have to be in heavy processing thread?
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
I can redesign and put a timer outside the processing thread. Still for my own knowledge i would like to know it there is a way of installing the QTimer inside a Thread.
Sorry for not pasting the original code. It is not my property and i cannot share it. As it is quite big i just tried to extract the highlights.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
You can put a timer anywhere you want, including in threads. But if you block the event loop of that thread then signals wont fly out and slots inside wont be executed. It's pretty straight forward.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
I agree with you. I do not know how to make these timer events propagate in my while() loop. According to docs: QCoreApplication::processEvents()
"Processes all pending events for the calling thread according to the specified flags until there are no more events to process."
So putting it inside a while() loop should do the job - sadly it does not, ..or i am doing something wrong.
Thank you anyway.
Re: QObject with QTimer moved to QThread - QTimer::timeout() not processed until wait
you could be doing any number of wrong things so I'm not going to speculate any further without code.