QTimer Class
QTimer 类提供了循环定时器和单次定时器。更多内容...
| 头文件: | #include <QTimer> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
| 继承自: | QObject |
- 所有成员列表,包括继承的成员
- 已弃用的成员
- QTimer 属于事件类。
属性
|
|
公共函数
| QTimer(QObject *parent = nullptr) | |
| virtual | ~QTimer() |
| QBindable<bool> | bindableActive() |
| QBindable<int> | bindableInterval() |
| QBindable<bool> | bindableSingleShot() |
| QBindable<Qt::TimerType> | bindableTimerType() |
| QMetaObject::Connection | callOnTimeout(Functor &&slot) |
| QMetaObject::Connection | callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection) |
(since 6.8) Qt::TimerId | id() const |
| int | interval() const |
| std::chrono::milliseconds | intervalAsDuration() const |
| bool | isActive() const |
| bool | isSingleShot() const |
| int | remainingTime() const |
| std::chrono::milliseconds | remainingTimeAsDuration() const |
| void | setInterval(int msec) |
| void | setInterval(std::chrono::milliseconds value) |
| void | setSingleShot(bool singleShot) |
| void | setTimerType(Qt::TimerType atype) |
| void | start(std::chrono::milliseconds interval) |
| int | timerId() const |
| Qt::TimerType | timerType() const |
公共槽位
信号
| void | timeout() |
静态公共成员
| void | singleShot(Duration interval, Functor &&functor) |
| void | singleShot(Duration interval, Qt::TimerType timerType, Functor &&functor) |
| void | singleShot(Duration interval, const QObject *context, Functor &&functor) |
| void | singleShot(Duration interval, Qt::TimerType timerType, const QObject *context, Functor &&functor) |
| void | singleShot(std::chrono::nanoseconds nsec, const QObject *receiver, const char *member) |
| void | singleShot(std::chrono::nanoseconds nsec, Qt::TimerType timerType, const QObject *receiver, const char *member) |
重新实现的受保护函数
| virtual void | timerEvent(QTimerEvent *e) override |
详细说明
QTimer类为定时器提供了一个高级编程接口。要使用它,请创建一个QTimer对象,将其timeout()信号连接到相应的槽函数,并调用start()。此后,它将以恒定间隔发出timeout()信号。
一个一秒(1000 毫秒)定时器的示例(摘自“模拟时钟”示例):
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
timer->start(1000);此后,每隔一秒就会调用update() 槽。
您可以通过调用setSingleShot(true) 使定时器仅触发一次。您还可以使用静态函数QTimer::singleShot() 在指定间隔后调用某个槽:
QTimer::singleShot(200, this, &Foo::updateCaption);在多线程应用程序中,您可以在任何具有事件循环的线程中使用 QTimer。若要从非 GUI 线程启动事件循环,请使用QThread::exec()。 Qt 使用定时器的 `thread affinity ` 来确定哪个线程将发出 `timeout()` 信号。因此,必须在该定时器所属的线程中启动和停止定时器;无法从其他线程启动定时器。
作为特例,超时时间为 0 的 QTimer 会尽快超时,尽管零超时定时器与其他事件源之间的执行顺序未作规定。零超时定时器可用于执行某些任务,同时仍能保持用户界面的响应迅速:
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Foo::processOneThing);
timer->start();此后,processOneThing() 将被反复调用。该函数应设计为始终快速返回(通常在处理完一个数据项后),以便 Qt 能在完成所有工作后立即将事件传递给用户界面并停止计时器。 这是在GUI应用程序中实现繁重任务的传统方法,但随着多线程技术如今在越来越多的平台上变得可用,我们预计零毫秒的QTimer对象将逐渐被QThread所取代。
精度与定时器分辨率
计时器的精度取决于底层操作系统和硬件。尽管大多数平台都支持 1 毫秒的分辨率,但在许多实际应用场景中,计时器的精度并不等同于该分辨率。
精度还取决于timer type 。对于Qt::PreciseTimer ,QTimer将尝试将精度保持在1毫秒。精确计时器也绝不会比预期更早超时。
对于Qt::CoarseTimer 和Qt::VeryCoarseTimer 类型,QTimer可能会在预期时间之前唤醒,但仍在这些类型的容差范围内:对于Qt::CoarseTimer ,容差为间隔的5%;对于Qt::VeryCoarseTimer ,容差为500毫秒。
如果系统繁忙或无法提供所需的精度,所有定时器类型都可能比预期更晚超时。在这种超时超限的情况下,即使有多个超时已到期,Qt 也会仅触发一次timeout(),然后恢复原始间隔。
QTimer 的替代方案
Qt 6.8 引入了 `QChronoTimer`。这两个类的主要区别在于,`QChronoTimer ` 支持更大的间隔范围和更高的精度(std::chrono::nanoseconds )。对于 `QTimer`,支持的最大间隔为 ±24 天,而对于 `QChronoTimer `,则为 ±292 年(当间隔超过std::numeric_limits<int>::max() 时,发生整数溢出的可能性更小)。 如果您仅需毫秒级精度和 ±24 天的范围,可以继续使用 QTimer。
另一种替代方案是在您的类中重写QObject::timerEvent()方法(该类必须是QObject 的子类),并采用以下方法之一:
- 使用QBasicTimer ,这是一个封装计时器ID的轻量级值类。你可以通过QBasicTimer::start()启动计时器,并通过QBasicTimer::stop()停止计时器。你可以在重写的timerEvent()中处理该事件。
- 一种更底层的方法是直接操作定时器 ID。要启动定时器,请调用QObject::startTimer(),并将返回的 ID 保存下来。要停止定时器,请调用QObject::killTimer()。您可以在自己重写的timerEvent() 中处理事件。与使用QBasicTimer 相比,这种方法通常更为繁琐。
使用timerEvent() 的一个缺点是,某些高级功能(如单次定时器和信号)不被支持。
某些操作系统会限制可使用的定时器数量;Qt 会尝试绕过这些限制。
另请参阅 QBasicTimer 、QTimerEvent 、QObject::timerEvent()、定时器和 模拟时钟。
属性文档
[bindable read-only] active : bool
注意:该 属性支持QProperty 绑定。
如果定时器正在运行,则此布尔属性为true ;否则为false。
访问函数:
| bool | isActive() const |
[bindable] interval : int
注意:此 属性支持QProperty 绑定。
该属性存储以毫秒为单位的超时间隔
该属性的默认值为 0。当QTimer 的超时间隔为 0 时,一旦窗口系统事件队列中的所有事件都被处理完毕,该 即会超时。
注意: 使用零计时器让 事件循环一直处于 忙碌状态 ,必然会导致问题,并使 UI 行为极不稳定。
设置正在运行的定时器的间隔将更改该间隔,调用stop(),然后调用start() 该定时器,并获取一个新的id()。如果定时器未运行,则仅更改间隔。
从 Qt 6.10 开始,设置负间隔会触发运行时警告,且该值将被重置为 1 毫秒。 在 Qt 6.10 之前,虽然可以为 Qt Timer 设置负间隔,但其行为可能出人意料(例如,如果计时器正在运行则会停止,或者根本不会启动)。
访问函数:
| int | interval() const |
| void | setInterval(int msec) |
| void | setInterval(std::chrono::milliseconds value) |
另请参阅 singleShot 。
[read-only] remainingTime : int
该属性保存剩余时间(以毫秒为单位)
返回计时器到超时为止的剩余时间(以毫秒为单位)。如果计时器处于非活动状态,返回值为 -1;如果计时器已过期,返回值为 0。
访问函数:
| int | remainingTime() const |
另请参阅 interval 。
[bindable] singleShot : bool
注意:此 属性支持QProperty 绑定。
该属性用于标识定时器是否为单次定时器
单次触发定时器仅触发一次,而非单次触发定时器则每interval 毫秒触发一次。
该属性的默认值为false 。
访问函数:
| bool | isSingleShot() const |
| void | setSingleShot(bool singleShot) |
另请参阅 interval 和singleShot()。
[bindable] timerType : Qt::TimerType
注意:此 属性支持QProperty 绑定。
控制计时器的精度
该属性的默认值为Qt::CoarseTimer 。
访问函数:
| Qt::TimerType | timerType() const |
| void | setTimerType(Qt::TimerType atype) |
另请参阅 Qt::TimerType 。
成员函数文档
[explicit] QTimer::QTimer(QObject *parent = nullptr)
根据给定的parent 创建一个定时器。
[virtual noexcept] QTimer::~QTimer()
销毁计时器。
template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(Functor &&slot)
在定时器的timeout()信号与slot 之间建立连接。返回该连接的句柄。
提供此方法是为了方便使用。它等同于调用:
注意: 当定义了QT_NO_CONTEXTLESS_CONNECT 时,此 重载不可用,请改用接受上下文对象的callOnTimeout()重载。
另请参阅 QObject::connect() 和timeout()。
template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
从timeout()信号创建一条连接至slot ,将其放置在context 的特定事件循环中,并返回该连接的句柄。
提供此方法仅为方便起见。它等同于调用:
此函数重载了QTimer::callOnTimeout()。
另请参阅 QObject::connect() 和timeout()。
[since 6.8] Qt::TimerId QTimer::id() const
如果定时器正在运行,则返回表示该定时器 ID 的 `Qt::TimerId `;否则返回 `Qt::TimerId::Invalid`。
该函数在 Qt 6.8 中引入。
另请参阅 Qt::TimerId 。
std::chrono::milliseconds QTimer::intervalAsDuration() const
返回该定时器的间隔,形式为std::chrono::milliseconds 对象。
另请参阅 interval 。
bool QTimer::isActive() const
如果计时器正在运行,则返回true ;否则返回false 。
注意: 这是属性active 的获取器 函数。
std::chrono::milliseconds QTimer::remainingTimeAsDuration() const
返回此定时器对象的剩余时间,格式为std::chrono::milliseconds 对象。如果该定时器已到期或逾期,则返回值为std::chrono::milliseconds::zero() 。如果无法找到剩余时间,或者定时器未运行,则该函数返回负数时长。
另请参阅 remainingTime()。
[static] template <typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Functor &&functor)
[static] template <typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Qt::TimerType timerType, Functor &&functor)
[static] template <typename Duration, typename Functor> void QTimer::singleShot(Duration interval, const QObject *context, Functor &&functor)
[static] template <typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Qt::TimerType timerType, const QObject *context, Functor &&functor)
该静态函数在调用 `interval` 之后会调用 `functor `。
使用此函数非常方便,因为您无需费心处理 `timerEvent `,也无需创建本地 `QTimer ` 对象。
如果指定了context ,则只有在间隔发生之前context 对象尚未被销毁的情况下,才会调用functor 。然后,该 functor 将在context 的线程上运行。上下文的线程必须有一个正在运行的 Qt 事件循环。
如果functor 是context 的成员函数,则该函数将在该对象上被调用。
interval 参数可以是int (解释为毫秒计数),也可以是std::chrono 类型(该类型会隐式转换为纳秒)。
从 Qt 6.10 开始,设置负间隔将导致运行时警告,并且该值将被重置为 1 毫秒。 在 Qt 6.10 之前,Qt Timer 虽然允许设置负间隔,但行为可能出人意料(例如,如果计时器正在运行则停止,或者根本不启动)。
注意:在 Qt 6.8 之前的版本中,chrono 的重载函数接受 chrono::milliseconds 类型,而非 chrono::nanoseconds 类型。编译器会自动为您进行转换,但当毫秒计数值极大时,该转换可能会发生溢出。
注意:此函数是可重入的。
另请参阅 start()。
[static] void QTimer::singleShot(std::chrono::nanoseconds nsec, const QObject *receiver, const char *member)
该静态函数会在给定时间间隔后调用一个插槽。
使用此函数非常方便,因为您无需处理timerEvent ,也无需创建本地QTimer 对象。
receiver 是接收对象,member 是槽。时间间隔由持续时间对象nsec 指定。
从 Qt 6.10 开始,设置负时间间隔将导致运行时警告,且该值会被重置为 1 毫秒。 在 Qt 6.10 之前,虽然 Qt Timer 允许设置负间隔,但其行为可能出人意料(例如,如果计时器正在运行则停止,或者根本不启动)。
注意:在 Qt 6.8 之前的版本中,此函数接受 chrono::milliseconds 类型,而非 chrono::nanoseconds。编译器会自动进行转换,但当毫秒计数值极大时,转换可能会导致溢出。
这是一个重载函数。
注意:此函数是可重入的。
另请参阅 start()。
[static] void QTimer::singleShot(std::chrono::nanoseconds nsec, Qt::TimerType timerType, const QObject *receiver, const char *member)
该静态函数会在给定时间间隔后调用一个插槽。
使用此函数非常方便,因为您无需处理timerEvent ,也无需创建本地QTimer 对象。
receiver 是接收对象,member 是槽。时间间隔由时长对象nsec 指定。timerType 影响计时器的精度。
从 Qt 6.10 开始,设置负间隔将导致运行时警告,且该值会被重置为 1 毫秒。 在 Qt 6.10 之前,Qt Timer 虽然允许设置负间隔,但行为可能出人意料(例如,如果计时器正在运行则会停止,或者根本不会启动)。
注意:在 Qt 6.8 之前的版本中,此函数接受 chrono::milliseconds 类型,而非 chrono::nanoseconds。编译器会自动进行转换,但当毫秒数极大时,转换可能会导致溢出。
这是一个重载函数。
注意:此函数是可重入的。
另请参阅 ` start()`。
[slot] void QTimer::start(int msec)
启动或重启计时器,超时间隔为msec 毫秒。
这相当于:
timer.setInterval(msec);
timer.start();如果计时器已经在运行,它将设置为stopped 并重新启动。这也会更改其id()属性。
如果singleShot 为 true,计时器将仅被触发一次。
从 Qt 6.10 开始,设置负间隔会引发运行时警告,且该值将被重置为 1 毫秒。 在 Qt 6.10 之前,Qt Timer 允许设置负间隔,但行为会出人意料(例如,如果计时器正在运行则停止,或者根本不启动)。
注意: 使用零间隔计时器占用 事件循环必然会引发问题,并导致用户界面行为极不稳定。
注意:此 槽已被重载。要连接此槽:
// Connect using qOverload:
connect(sender, &SenderClass::signal,
timer, qOverload(&QTimer::start));
// Or using a lambda as wrapper:
connect(sender, &SenderClass::signal,
timer, [receiver = timer](int msec) { receiver->start(msec); }); [slot] void QTimer::start()
启动或重启计时器,并使用interval 中指定的超时时间。
如果计时器正在运行,则会将其stopped 并重新启动。这也会改变其id()属性。
如果 `singleShot ` 为真,计时器将仅被激活一次。
注意: 使用零计时器占用 事件循环必然会导致问题,并造成用户界面行为极不稳定。
注意:此 插槽已被重载。要连接到此插槽:
// Connect using qOverload:
connect(sender, &SenderClass::signal,
timer, qOverload<>(&QTimer::start));
// Or using a lambda as wrapper:
connect(sender, &SenderClass::signal,
timer, [receiver = timer]() { receiver->start(); });void QTimer::start(std::chrono::milliseconds interval)
启动或重启计时器,超时时间为interval 毫秒。
这相当于:
timer.setInterval(interval);
timer.start();如果计时器正在运行,它将设置为stopped 并重新启动。这也会改变其id() 属性。
如果singleShot 为 true,则计时器仅会被触发一次。
从 Qt 6.10 开始,设置负间隔会引发运行时警告,且该值将被重置为 1 毫秒。 在 Qt 6.10 之前,Qt 定时器允许您设置负间隔,但行为会出人意料(例如,如果定时器正在运行则停止,或者根本不启动)。
注意: 使用零间隔计时器占用 事件循环,必然会导致问题,并使 UI 表现得非常不稳定。
这是一个重载函数。
[slot] void QTimer::stop()
停止计时器。
另请参阅 start()。
[private signal] void QTimer::timeout()
当计时器超时,将发出此信号。
注意:这是一个 私有信号。它可以在信号连接中使用,但用户无法触发该信号。
另请参阅 interval 、start() 以及stop()。
[override virtual protected] void QTimer::timerEvent(QTimerEvent *e)
重写了:QObject::timerEvent(QTimerEvent *event)。
int QTimer::timerId() const
如果定时器正在运行,则返回该定时器的 ID;否则返回 -1。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.