Why is a call to QTimer::start() outside a QThread (event loop) not failing?
该文件说
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.
所以我希望这段代码...
1 2 3 4 5 6 7 8 9
| int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QTimer timer;
timer.start(1000);
app.exec();
} |
...失败,因为我在其中调用start的主线程不是QThread和Timers can only be used with threads started with QThread
题
为什么这不会失败?
似乎您没有正确理解文档所指示的内容,让我们分析语句的每个部分:
In multithreaded applications, you can use QTimer in any thread that has an event loop.
您在哪里使用了QTimer的事件循环? 是的,您正在主线程中使用QTimer,并且已通过QXApplication创建了事件循环。
To start an event loop from a non-GUI thread, use QThread::exec()
主线程是非GUI线程吗? 不,因此在这种情况下,不必在主线程中使用QThread来使用QTimer。
QTimer在什么情况下会失败? 如果QTimer在主线程中运行,而您尚未创建QXApplication,或者在没有Qt事件循环的std :: thread线程中运行它。
结论:
如果在主线程中使用了QTimer,则只需运行QXApplication,如果要在另一个线程中使用它,则必须使用QThread。 换句话说,QTimer仅在存在Qt事件循环的情况下起作用。
-
我在事件循环之外调用了start,所以答案是否定的。
-
@Bob mmm,您在使用QApplication时创建了一个事件循环,因此QTimer不会失败。
-
但是计时器在我称为qtimer :: start()的那一点如何了解应用程序?
-
您在事件循环未启动之前调用start()的@Bob并不是问题,文档指出QTimer必须存在于事件循环中,例如,如果要使用app.exec()而不是使用睡眠,那么将不存在事件循环,因此QTimer将永远不会触发。
-
@Bob,但是计时器如何在我称为qtimer :: start()的那一点上了解应用程序?使用start()方法,您只是告诉QTimer,当事件循环存在时,必须启动QTimer的逻辑,如果没有事件循环,则QTimer将无法工作。
-
当我调用app.exec()时,是否不会创建与main()线程分开的新线程?
-
@Bob不,只是一个事件循环。您了解什么是事件循环吗?阅读wiki.qt.io/Threads_Events_QObjects
-
@Bob用另一种方式重新表达了这个出色的答案(您应该接受:),QThread::start()不会失败,因为它不在QXApplication的另一个线程中...尚未在任何线程中。计时器不会自行启动线程或事件循环。在没有事件循环的情况下,它不会做任何事情,该事件由QXApplication启动...然后启动计时器。您还可以在主应用程序循环开始之前用Qt::QuedConnection或QCoreApplication::postEvent()进行QMetaObject::invokeMethod()之类的操作,并且它将起作用(但仅在循环开始之后)。
-
@eyllanesc我认为那里有错字? 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.是,主线程是非GUI线程。
-
@Bob这不是一个错字,但是有必要将其上下文化为非GUI线程,例如,如果它只是一个控制台应用程序,那么是否会有一个GUI线程?好吧,因为没有GUI,所以不会,因此主线程是非GUI线程,但这不是非GUI线程的含义。当Qt引用非GUI线程时,它引用的不是主线程,因为GUI通常位于主线程中。
-
@Bob [续]总之,GUI线程与Qt的主线程相同。阅读文档:此线程称为"主线程"(在Qt应用程序中也称为" GUI线程")doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-第三广告