我有以下代码:
mytimer.cpp
#include "mytimer.h"
#include <QtCore>
MyTimer::MyTimer()
{
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(mySlot()));
timer->start(1000);
}
void MyTimer::mySlot()
{
qDebug()<<"timer executed";
}
并在 main.cpp
中#include <QCoreApplication>
#include "mytimer.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyTimer mtimer;
qDebug()<<"DONE";
return a.exec();
}
现在输出如下:
DONE
timer executed
timer executed
...
...
...
...
infinite sequence
我真的很困惑。我们的主要功能如何完成,SLOT mySlot()
的代码仍在执行?
这有什么重要方面?我需要了解吗?
当我将 mytimer.cpp MyTimer()修改为:
时,会发生什么变化MyTimer::MyTimer()
{
timer = new QTimer(this);
QEventLoop eventloop;
connect(timer,SIGNAL(timeout()),this,SLOT(mySlot()));
connect(timer,SIGNAL(timeout()),&eventloop,SLOT(quit()));
timer->start(1000);
eventloop.exec();
}
在打印 DONE 之前,有一个计时器已执行。具体来说,输出现在变为:
timer executed
DONE
timer executed
timer executed
...
...
...
...
infinite sequence
是什么导致单独的计时器执行出现在完成之上?
答案 0 :(得分:3)
不 - 您的主要功能尚未完成。它调用了a.exec(),它永远不会在你的应用程序中返回。
a.exec()依次处理“消息队列”,触发所有调用mySlot()的定时器事件。
答案 1 :(得分:3)
a.exec
启动事件循环。在QApplication::exit()
或QApplication::quit()
或所有窗口关闭之前,它不会返回值。
答案 2 :(得分:2)
是什么导致执行单独的计时器显示在DONE之上?
计时器信号始终从最外层的事件循环中发出 - 因为控制点所在的位置(即线程正在运行的位置 - 它&# 39;在Qt内部)。由于您旋转了本地事件循环(eventloop.exec();
),这是定时器调用的来源。一旦完成该事件循环并且exec()
已返回,MyTimer
构造函数已退出,DONE
被打印出来,并且剩余的计时器调用从主事件循环发生。
一般来说,嵌套事件循环的代码会被破坏,所以如果你发现自己在调用堆栈中有多个exec()
,那么你做错了。有一些值得注意的例外:由于OS X API缺陷,OS X上的本机对话需要自己的嵌套事件循环,QDrag
需要exec()
也很可能是由于平台缺陷需要{{1}对于可移植性,即使在某些平台上它也是不必要的。