QTimer in QThread doesn't start or timeout
Hi there,
I am playing around with QThreads for the first time. And now I have the weird problem that the QTimer in my thread class doesn't start or emit the timeout() signal. Some code:
Code:
CanThread
::QCanThread( QObject* parent
){
m_countTimer
= new QTimer( this );
m_countTimer->setInterval( 1000 );
connect( m_countTimer, SIGNAL(timeout()), this, SLOT(updateCounter()) );
}
void CanThread::run() {
m_countTimer->start();
exec();
}
void CanThread::stop() {
m_countTimer->stop();
this->quit();
}
void QCanThread::updateCounter() {
m_currentCounter++;
emit showCurrentCounter( m_currentCounter );
}
The timer m_countTimer shall timeout all 1000ms. As reaction a counter variable is incremented and the GUI is signalled to display that variable.
(I know it is bullshit to do this that way. A simple timer and the GUI without my CanThread would be enough, but I want get a feeling how deal with threads)
But the slot updateCounter() is never called. Either the timer doesn't start when I call threadObject->start() or the timer doesn't emit its signal timeout().
What is wrong with my code?
Re: QTimer in QThread doesn't start or timeout
couple of things:
1. QCanThread? just a typo?
2. catch the value returned by connect and see if the signal is connected to slot
rest looks fine
Re: QTimer in QThread doesn't start or timeout
1. I thought I had removed all 'Q's not to confuse anyone ;).
2. connect() returns "true".
If I add a
QTimer::singleShot(1000, this, SLOT(updateCounter()));
after
m_countTimer->start();
the GUI displays the counter value after a second. But the interval timer still doesn't work. Now I am confused :confused:.
Re: QTimer in QThread doesn't start or timeout
strange..ok, try checkin the timer ids in constructor and run method..another thing u can try is move all the code from constructor to run method..just for playin around
Re: QTimer in QThread doesn't start or timeout
The Qt doc tells the timer ID is -1 while timer is not running. So the ID is -1 in my constructor.
After calling start() the ID is a positive number.
When I create and set the interval of the timer in the run() method it works as expected. My GUI is constantly increasing the value.
So there must be a difference in timer objects created in thread constructors and timers created later (e.g. after starting the thread).
Re: QTimer in QThread doesn't start or timeout
actually thats how threads are supposed to work..whatever code u wanna execute should be in run method..thats when a thread actually kicks off..in every documentation they say, derive from base class and implement run..i believe if u connect in run() and do other initialization in constructor, it should work too..
Re: QTimer in QThread doesn't start or timeout
No. Timer creation has to be done in run(). If only connect() is done in run() it doesn't work.
Re: QTimer in QThread doesn't start or timeout
hmm..this whole situation is definitely a bit weird..cuz the documentation should mention that any kind of initialization done in the constructor would not take any effect when the thread is actually run..and although it makes sense that run method should have all the initialization, one can always make a mistake of initializing in constructor being a C++ developer....any guru thoughts on this?
Re: QTimer in QThread doesn't start or timeout
I don't know if you sove that, but that maybe help others.
Call in class constructor:
this->moveToThread(this);
countTimer->moveToThread(this);
Re: QTimer in QThread doesn't start or timeout
Added after 4 minutes:
Quote:
hmm..this whole situation is definitely a bit weird..cuz the documentation should mention that any kind of initialization done in the constructor would not take any effect when the thread is actually run..and although it makes sense that run method should have all the initialization, one can always make a mistake of initializing in constructor being a C++ developer....any guru thoughts on this?
this is because what you code you do in constructor is done in the calling thread. The code in run will be executed in the new thread after start() is called. timers dont work well across thread boundaries so you either need to instantiate the timer in run() or use moveTothread() in run to move the timer.
Quote:
Originally Posted by
israelins
I don't know if you sove that, but that maybe help others.
Call in class constructor:
this->moveToThread(this);
countTimer->moveToThread(this);
that is ridiculous :-/