QObject 是所有 Qt 对象的基类,在 Qt 中提供基本计时器支持。采用 QObject::startTimer (), you start a timer with an interval in milliseconds as argument. The function returns a unique integral timer ID. The timer will then fire at regular intervals until you explicitly call QObject::killTimer () with that timer ID.
Instead of handling timer IDs directly, you can use QBasicTimer . QBasicTimer is a value-class, RAII wrapper around a timer ID. You start the timer with QBasicTimer::start (), and stop it with QBasicTimer::stop () (the latter is also called upon destruction). To use QBasicTimer ,必须重实现 timerEvent () in your class (which must be a sub-class of QObject ), and handle the timer event there.
For this mechanism to work, the application must run in an event loop. You cat start an event loop with QApplication::exec ()。当计时器激发时,应用程序发送 QTimerEvent ,并控制流离开事件循环,直到计时器事件被处理。这隐含计时器无法被激发,当应用程序忙于做某些事情时。换句话说:计时器精度从属应用程序的粒度。
在多线程应用程序中,可以在拥有事件循环的任何线程中使用计时器机制。要从非 GUI 线程启动事件循环,使用 QThread::exec ()。Qt 使用对象的 线程亲缘关系 确定哪个线程将交付 QTimerEvent 。因此,必须启动和停止对象线程中的所有计时器;为另一线程中的对象启动计时器,是不可能的。
计时器功能的主要 API 是 QTimer . QTimer stores the interval in a signed integer, which limits the maximum interval it supports to the number of milliseconds that can fit in a signed integer (in practice, this is a period of around 24 days).
Qt 6.8 introduced the
QChronoTimer
class. The main difference between the two classes is that
QChronoTimer
supports a larger interval range and a higher precision (
std::chrono::nanoseconds
). For
QTimer
the maximum supported interval is ±24 days, whereas for
QChronoTimer
it is ±292 years. If you only need millisecond resolution and ±24 days range, you can continue to use
QTimer
。注意,
QChronoTimer
exists mainly because
QTimer
's precision couldn't be changed to
std::chrono::nanoseconds
without breaking binary-compatibility.
The accuracy of the timers depends on the underlying operating system. Windows 2000 has 15ms accuracy; other systems that we have tested can handle 1ms intervals.
QTimer provides regular timers that emit a signal when the timer fires, and inherits from QObject 因此,它能很好适应大多数 Qt 程序的所有权结构。正常使用它的方式像这样:
QTimer *timer = new QTimer(1s, this);
connect(timer, &QTimer::timeout, this, &MyWidget::processOneThing);
timer->start();
auto *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyWidget::processOneThing);
timer->setInterval(1s);
timer->start();
The
QTimer
object is made into a child of the
this
对象,因此当
this
is destroyed, the timer is destroyed too. Next, the
timeout
() signal is connected to the slot that will do the work, the timer interval can be either passed to the constructor, or set later on with setInterval().
QTimer also provides static functions for single-shot timers. For example:
MyWidget widget;
QTimer::singleShot(200ms, &widget, &MyWidget::updateCaption);
200ms after this line of code is executed, the
updateCaption()
槽将被调用。
For QTimer 要工作,应用程序必须拥有事件循环;也就是说,必须调用 QCoreApplication::exec () 在某些地方。才交付计时器事件,当事件循环在运行时。
在多线程应用程序中,可以使用 QTimer 在拥有事件循环的任何线程中。要从非 GUI 线程启动事件循环,使用 QThread::exec ()。Qt 使用计时器的 线程亲缘关系 确定哪个线程将发射 timeout () 信号。因此这,必须在其线程中启动和停止计时器;从另一线程启动计时器,是不可能的。
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); setWindowTitle(tr("Analog Clock")); resize(200, 200); }
每秒, QTimer 会调用 QWidget::update () 槽以刷新时钟的显示。