简述

QObject是所有Qt objects的基类,在Qt中提供了基础定时器的支持。使用QObject::startTimer(),你可以传递一个毫秒数间隔作为参数启动一个定时器。该函数返回一个唯一的整数timer ID,计时器会定时触发,直到你显式地传递timer ID调用QObject::killTimer()。
对于这种工作机制,应用程序必须在事件循环(event loop)中运行,使用QApplication::exec()启动一个事件循环。当一个定时器触发时,应用程序会发送一个QTimerEvent,并且控制流离开事件循环,直到定时器事件被处理。这意味着,当你的应用程序正忙着做别的事情时,定时器不能触发。换句话说,计时器的精度取决于应用程序的粒度。
在多线程应用程序中,你可以在有一个事件循环的任何线程中使用定时器机制。要从一个非GUI线程启动事件循环,使用QThread::exec()。Qt使用对象的线程关联来确定哪个线程将传送QTimerEvent。正因如此,你必须启动和停止该对象的线程的所有计时器,不可能在另一个线程的对象中启动定时器。

详细说明

主要的计时器功能API在QTimer中,这个类提供了常规的定时器。当定时器触发就会发射信号,而继承自QObject以便适合大多数GUI程序的所有权结构。正常使用它的方法是这样的:

  1. QTimer *timer = new QTimer(this);
  2. connect(timer, &QTimer::timeout(), this, [](){
  3. qDebug() << "QTimer 1000...";
  4. });
  5. timer->start(1000);

QTimer对象作为这个部件的孩子,当此部件被删除时,计时器也被删除。接下来,连接timeout()信号与槽函数,以1000毫秒的间隔启动定时器,表明它将每秒钟都会超时。

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

  1. QTimer::singleShot(200, this, SLOT(updateCaption()));

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

为了让QTimer可以运行,你必须在应用程序中有一个事件循环;也就是说,你必须在某个地方调用QCoreApplication::exec(),定时器事件只在事件循环运行时被传送。

在多线程应用程序中,你可以在有一个事件循环的任何线程中使用QTimer。要从一个非GUI线程启动事件循环,使用QThread::exec()。Qt使用定时器的 thread affinity来确定哪个线程将发射timeout()信号。正因如此,你必须启动和停止计时器在它自己的线程中,不可能在另一个线程的对象中启动定时器。