定时器

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);

QTimer 对象变为 this 对象的子对象,以便当 this 对象被删除时,定时器也会被删除。然后,将其 timeout() 信号连接到将执行工作的槽,并以 1000 毫秒的值启动,表示每秒超时一次。

QTimer 还提供了一个用于单次触发定时器的静态函数。例如

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

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

为了使 QTimer 能够工作,应用程序中必须有一个事件循环;也就是说,你必须在某处调用 QCoreApplication::exec()。定时器事件只在事件循环运行期间传递。

在多线程应用程序中,您可以在任何具有事件循环的线程中使用 QTimer。要从非GUI线程启动事件循环,请使用 QThread::exec()。Qt 使用计时器的 线程亲和力 来确定哪个线程将发出 timeout() 信号。因此,您必须在计时器的线程中启动和停止它;不能从另一个线程启动计时器。

模拟时钟 示例展示了如何使用 QTimer 在固定间隔时间重绘小部件。从 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,您必须在您的 QObject 子类中重新实现 timerEvent() 并在那里处理超时。

© 2024 The Qt Company Ltd。此处包含的文档贡献是各自所有者的版权。此处提供的文档根据自由软件基金会发布的 GNU自由文档许可版1.3 的条款提供。Qt 和相关标志是 The Qt Company Ltd. 在芬兰及其他国家和地区的商标。所有其他商标均为各自所有者的财产。