我在Windows7平台上使用Qt5。
在我当前的应用程序中,我需要一个计时器,从 00 分钟到 59 分钟每分钟(“每分钟”)触发...
我尝试了各种想法,但我的(以前的)解决方案存在一些问题,例如:失火(某一分钟没有触发超时)或双火(同一分钟触发两次超时!)。
最后,我目前达到了这个实现:
static QTimer timer;
static int GetInterval()
{
QDateTime now(QDateTime::currentDateTime());
return ((60 - now.time().second()) * 1000 - now.time().msec());
}
void TEST_TIMER(void)
{
QObject::connect(&timer, &QTimer::timeout, []()
{
qDebug() << " Triggered! " << QDateTime::currentDateTime().time().minute()
<< QDateTime::currentDateTime().time().second()
<< QDateTime::currentDateTime().time().msec();
timer.start(GetInterval());
} );
timer.start(GetInterval());
}
这是输出:
Triggered! 34 59 550
Triggered! 35 0 3
Triggered! 36 0 15
Triggered! 37 0 28
Triggered! 38 0 41
Triggered! 39 0 54
Triggered! 40 0 68
Triggered! 41 0 82
Triggered! 42 0 97
Triggered! 43 0 109
Triggered! 44 0 123
Triggered! 45 0 137
Triggered! 46 0 149
Triggered! 47 0 165
Triggered! 48 0 178
Triggered! 49 0 192
Triggered! 50 0 205
Triggered! 51 0 217
Triggered! 52 0 231
Triggered! 53 0 244
...
看起来不错,除了第一行: 已触发! 34 59 550
:( 为什么?
另外,为什么会有大约 12-13 毫秒/分钟的上升速度?
所以,我不是这方面的专家,我更愿意问:
这个实现可以吗?是否可以改进以避免出现双发和/或失火等不愉快的情况?
最佳答案
来自 QTimer description (Qt::CoarseTimer
是默认设置):
For Qt::CoarseTimer and Qt::VeryCoarseTimer types, QTimer may wake up earlier than expected, within the margins for those types: 5% of the interval for Qt::CoarseTimer and 500 ms for Qt::VeryCoarseTimer.
因此,如果准确率为 5%,您的第一枪可能会比预期早得多,这解释了:
Triggered! 34 59 550
Triggered! 35 0 3
如果计时器(恰好)在 0 分钟之前计时,它会再次计时以对齐尚未到达的分钟,即使它还有几毫秒。
如果您使用 Qt::PreciseTimer
代替,它永远不会比预期更早超时,因此您不会遇到这个问题(确保用几毫秒填充延迟)。
Qt::CoarseTimer
也可能解释了您看到的小漂移,因为没有任何内容表明误差幅度是随机的。
关于Qt: 如何实现 "per minute"定时器?避免失火和双火的更好选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34872552/