计时器

QObject 是所有 Qt 对象的基类,在 Qt 中提供基本计时器支持。采用 QObject::startTimer (),启动计时器采用以毫秒为单位的间隔作为自变量。函数返回唯一整数计时器 ID。现在将按定期间隔激发计时器,直到明确调用 QObject::killTimer () 采用计时器 ID。

要使此机制工作,必须在事件循环中运行应用程序。启动事件循环采用 QApplication::exec ()。当计时器激发时,应用程序发送 QTimerEvent ,并控制流离开事件循环,直到计时器事件被处理。这隐含计时器无法被激发,当应用程序忙于做某些事情时。换句话说:计时器精度从属应用程序的粒度。

在多线程应用程序中,可以在拥有事件循环的任何线程中使用计时器机制。要从非 GUI 线程启动事件循环,使用 QThread::exec ()。Qt 使用对象的 线程亲缘关系 确定哪个线程将交付 QTimerEvent 。因此,必须启动和停止对象线程中的所有计时器;为另一线程中的对象启动计时器,是不可能的。

间隔值上限可以按有符号整数指定的毫秒数确定 (实践中,此周期仅仅 24 天多一点)。精度从属底层操作系统。Windows 2000 拥有 15 毫秒精度;测试过的其它系统,可以处理 1 毫秒间隔。

计时器功能的主要 API 是 QTimer 。该类提供发射信号的常规计时器当计时器被激发时,且继承 QObject 因此,它能很好适应大多数 Qt 程序的所有权结构。正常使用它的方式像这样:

    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Foo::updateCaption);
    timer->start(1000);
					

The QTimer 对象被制作成子级 this 对象,因此当 this 对象被删除,计时器也会被删除。接下来,其 timeout () 信号将被连接到履行工作的槽,按 1000 毫秒值启动,指示它将每秒超时。

QTimer 还为单发计时器提供静态函数。例如:

    QTimer::singleShot(200, this, &Foo::updateCaption);
					

200 毫秒 (0.2 秒) 后执行此行代码, updateCaption() 槽将被调用。

For QTimer 要工作,应用程序必须拥有事件循环;也就是说,必须调用 QCoreApplication::exec () 在某些地方。才交付计时器事件,当事件循环在运行时。

在多线程应用程序中,可以使用 QTimer 在拥有事件循环的任何线程中。要从非 GUI 线程启动事件循环,使用 QThread::exec ()。Qt 使用计时器的 线程亲缘关系 确定哪个线程将发射 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.

The 指针式时钟 范例展示如何使用 QTimer 以按定期间隔重新绘制 Widget。来自 AnalogClock 的实现:

AnalogClock::AnalogClock(QWidget *parent)
    : QWidget(parent)
{
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
    timer->start(1000);
    ...
}
					

每秒, QTimer 会调用 QWidget::update () 槽以刷新时钟的显示。

若已经拥有 QObject 子类且想要轻松优化,可以使用 QBasicTimer 而不是 QTimer 。采用 QBasicTimer ,必须重实现 timerEvent () 在您的 QObject 子类并在那里处理超时。 Tetrix 范例展示如何使用 QBasicTimer .