【QT】计时器

计时器

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(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() 并在那里处理超时。"摇摆"示例展示了如何使用 QBasicTimer。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值