Hi all,
I recently bumped into some curious behavior while implementing a program that uses QThreads.
Consider a "MyThread" class (a subclass of QThread) that implements an "updateTimerFired()" slot method. MyThread's "run" method instantiates a QTimer, connect the timer's timeout() signal to MyThread's updateTimerFired() slot, starts the timer, then executes exec() -- starting MyThread's private exec() loop.
The updateTimerFired() slot gets repeatedly executed as it should, but here's the catch: in what thread do you think that it runs?
Much to my surprise, it is executed not in MyThread's thread, but in the thread that has instantiated MyThread (in my case, the main thread).
To verify for yourself, you can download http://wopr.jigsaw.nl/wtf.tar.gz.
I think this behavior is completely counter-intuitive. Upon examining the Qt documentation, I found only a single line that explains this behavior:
http://doc.trolltech.com/4.4/threads...across-threads
"With queued connections, the slot is invoked when control returns to the event loop of the thread to which the object belongs. The slot is executed in the thread where the receiver object lives."
So what this boils down to is this: if a QThread derivative has a slot, it will not get executed by its own event loop, in its own thread. Therefore, you should be very wary of using slots in a QThread derivative, or even slots in a member function of a QThread-derived class. If you want a slot to be execute in the thread itself, this will only work if you instantiate the object with the slot within the run() method.
My feeling (after spending a day of chasing this issue) is that the Qt documentation could (or rather should) be a lot more specific to this. In particular, I think this should be mentioned in the documentation of the QThread class.
Any thoughts?
Bookmarks