我最近在使用QTimer调用具有内部QEventLoop的函数时偶然发现了这个
所以,假设我们有一个QTimer实例
QTimer* timer = new QTimer;
在构造函数的某个地方,我们启动它,它开始每100毫秒滴答一次
timer->start(100);
现在是有趣的部分,我们将它连接到具有内部QEventLoop
的插槽void SlotFunction()
{
qDebug() << "entered";
QEventLoop loop;
loop.exec();
}
撇开这个循环真的是多么愚蠢,我们看到我们永远不会完成处理插槽和计时器的后续超时将继续堆叠到执行队列中。一切都很好,应该如此。
接下来应该是什么不是:因为QEventLoop确保我们的应用程序保持响应,而插槽无意识地闲置,我们可以创建一个按钮及其单击的()插槽,如下所示:
void OnClicked()
{
timer->start(100);
}
我在这里做的事实上是重新启动当前的计时器周期,仅此而已,仅此而已。对?不!重新启动后,SlotFunction再次触发 ,提示计时器重启后的勾号实际上并不等于之前发出的所有其他滴答......
我唯一的问题是: WTF?!为什么手动重启定时器会让它进入插槽的额外时间?我问freenode,但我得到的唯一答案是&#34;它应该是&#34;
答案 0 :(得分:3)
我尝试了这一点,每次点击都会创建另一个&#34;输入&#34;线。
主要的Eventloop无法处理另一个事件,因为我们陷入了新的事件循环。
在实现第二个插槽并将此插槽连接到超时信号时,很容易看到。
timeout()
,则新的eventloop将检查计时器。 代码:
#include <QDebug>
#include <QTime>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer;
timer->setInterval(2000);
connect(timer,SIGNAL(timeout()),this,SLOT(timerslot()));
connect(timer,SIGNAL(timeout()),this,SLOT(timerslot2()));
timer->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
timer->start(2000);
}
void MainWindow::timerslot()
{
qDebug()<<"In";
QEventLoop loop;
loop.exec();
}
void MainWindow::timerslot2()
{
qDebug()<<"More";
}
开始时的输出:
In
每次点击输出:
In
点击3次后输出:
In
In
In
In
退出应用程序的输出:
In
In
In
In
More
More
More
More