QTimer启动功能到底发生了什么?

时间:2017-02-05 11:52:52

标签: c++ qt

我有以下代码:

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

是什么导致单独的计时器执行出现在完成之上?

3 个答案:

答案 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}对于可移植性,即使在某些平台上它也是不必要的。