4

The documentation 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 I'd expect this code...

int main(int argc, char *argv[])
{
  QCoreApplication app(argc, argv);
  QTimer timer;
  timer.start(1000);

  app.exec();

}

...to fail because the main thread, where I'm calling start, is not a QThread and Timers can only be used with threads started with QThread

QUESTION

Why doesn't this fail?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Bob
  • 4,576
  • 7
  • 39
  • 107

1 Answers1

5

It seems that you have not understood correctly what the documentation indicates, let's analyze each part of the statement:


In multithreaded applications, you can use QTimer in any thread that has an event loop.

Where did you use the QTimer is there an event loop? Yes, you are using the QTimer in the main thread and you have created the event loop through the QXApplication.

To start an event loop from a non-GUI thread, use QThread::exec()

Is the main thread a non-GUI thread? No, so it is not necessary in this case to use QThread to use a QTimer in the main thread.

In what cases can QTimer fail? If the QTimer runs in the main thread and you have not created a QXApplication, or if you run it in a thread where there is no Qt event loop as std::thread.


Conclusion:

If the QTimer is used in the main thread, just run the QXApplication, if you want to use it in another thread then you must use QThread. In other words, QTimer only works if there is a Qt event loop.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I called `start` outside of a event loop so the answer is no. – Bob Oct 18 '19 at 23:36
  • @Bob mmm, you have created an event loop when using QApplication so QTimer will not fail. – eyllanesc Oct 18 '19 at 23:37
  • but how does timer know about app at the point I called qtimer::start()? – Bob Oct 18 '19 at 23:39
  • @Bob that you call start () before the event loop does not start is not a problem, what the docs points out is that the QTimer must live in an event loop, for example if instead of using app.exec() you will use sleep then no the eventloop would exist so the QTimer would never fire. – eyllanesc Oct 18 '19 at 23:40
  • @Bob **but how does timer know about app at the point I called qtimer::start()?** With the start() method you are only telling the QTimer that when the eventloop exists then the logic of the QTimer must be started, if there is no event loop then the QTimer will not work. – eyllanesc Oct 18 '19 at 23:42
  • When I call app.exec(), does it not create a new thread which is separate from the main() thread? – Bob Oct 18 '19 at 23:43
  • @Bob No, just an event loop. Do you understand what an event loop is? Read https://wiki.qt.io/Threads_Events_QObjects – eyllanesc Oct 18 '19 at 23:44
  • 1
    @Bob To rephrase this excellent answer (which you should accept :) another way, the `QThread::start()` doesn't fail because it is not in _another_ thread from QXApplication... it's not in _any_ thread, yet. The timer does not start a thread or event loop on its own. It will not do anything w/out an event loop, which QXApplication starts... which then starts the timer. You can also do things like `QMetaObject::invokeMethod()` with `Qt::QuedConnection`, or `QCoreApplication::postEvent()`) before the main app loop starts, and it will work (but _only_ once the loop starts). – Maxim Paperno Oct 19 '19 at 00:40
  • @eyllanesc I think there's typo? `Is the main thread a non-GUI thread? No, so it is not necessary in this case to use QThread to use a QTimer in the main thread.` Yes, the main thread is a non-GUI thread. – Bob Oct 24 '19 at 15:51
  • @Bob It is not a typo, but it is necessary to contextualize that it is non-GUI thread, for example if it is only a console application, then could there be a GUI thread? Well, for not having a GUI there would not be and therefore the main-thread is non-GUI thread, but that is not the meaning of non-GUI thread. When Qt refers to non-GUI thread, it refers to a thread other than the main thread, since the GUI generally lives in the main thread. – eyllanesc Oct 24 '19 at 15:57
  • @Bob [cont.] In conclusion GUI thread is the same as main thread for Qt. Read the docs: *This thread is called the "main thread" (also known as the "GUI thread" in Qt applications)* https://doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-thread – eyllanesc Oct 24 '19 at 15:57