2

In the documentation it says:

In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit the timeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.

So when I have a QTimer object, Qt uses the object's (or it's parent's) thread affinity to determine which thread will emit the timeout() signal.
But what happens when I use the static member function singleShot(..) which does not need a QTimer instance, which thread will emit the timeout signal then?

Delgan
  • 18,571
  • 11
  • 90
  • 141
user2950911
  • 873
  • 3
  • 12
  • 19

2 Answers2

4

Qt is open source so best approach is to check source code. So object of internal class QSingleShotTimer is created (it is QObject but not QTimer).
The most important line that ansewers you question is here:

  connect(this, SIGNAL(timeout()), receiver, member);

There is no moveToThread so it works like that:

  1. temporary object is created for current thread
  2. the signal is emitted from that thread
  3. the slot is called immediately if destination object is assigned to same thread
  4. otherwise the slot invocation is queued in event loop of thread to which target belongs to.

see documentation of connect and values of its 5-th parameter (type of connection).

Note that if msec value is zero then invocation of slot is queued in even loop of thread which receiver belongs to (no temporary object is created).

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • I've observed a `singleShot` timer never actually executing its callback; I haven't produced a minimal complete example (so it's not worth opening a new question), but I'm *guessing* it has something to do with thread affinity. So I'm wondering if, in my version of Qt (I think it's 5.6.2-1), `singleShot` timers started in the wrong thread can actually fail to trigger the callback. – Kyle Strand Sep 30 '16 at 17:33
  • I'm betting you are invoking `singleShot` from thread which doesn't return control to event loop. Event loop processing is needed so `QTimer` could work. – Marek R Sep 30 '16 at 19:21
1

The QTimer::singleShot() function creates a QTimer object and does all the setup for the signals and cleanup internally.

The thread affinity will be to whichever thread was running that executed that function.

RobbieE
  • 4,280
  • 3
  • 22
  • 36
  • 1
    you are wrong, see my answer. `QTimer` is not created, but some object of internal class `QSingleShotTimer`. – Marek R Mar 11 '14 at 10:08