Qt5.12 两种定时器 介绍

扣扣技术交流群:460189483

如果我们在某个类中要用到定时器的功能,可以选择两种方式:

1.如果此类继承于QObject,可以直接调用以下函数:

int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)

此函数开启一个定时器,但只返回该定时器的编号,我们无法获取定时器对象(即使创建了定时器对象也不应该是QTimer类型的,因为,这是在QObject类中的成员函数,不应该出现子类QTimer的身影),所以也无法使用信号与槽机制,只能通过重载定时器事件处理函数:

[virtual protected] void QObject::timerEvent(QTimerEvent *event)

在timerEvent()函数中可以通过定时器Id来区分多个定时器,并分别处理;

关闭定时器可以在类中调用以下函数:

void QObject::killTimer(int id)

此函数的参数为定时器的Id。

这里引用一下Qt Assistant中example:

  class MyObject : public QObject
  {
      Q_OBJECT
 
  public:
      MyObject(QObject *parent = 0);
 
  protected:
      void timerEvent(QTimerEvent *event);
  private:
        int timerID1;
        int timerID2;
        int timerID3;
  };
 
  MyObject::MyObject(QObject *parent)
      : QObject(parent)
  {
      timerID1 = this->startTimer(50);     // 50-millisecond timer
      timerID2 = this->startTimer(1000);   // 1-second timer
      timerID3 = this->startTimer(60000);  // 1-minute timer
  }
 
  void MyObject::timerEvent(QTimerEvent *event)
  {
      int id = event->timerID();
      switch(id)
      {
        case timerID1:
            qDebug() << "Timer ID:" << timerID1;
            break;
        case timerID2:
            qDebug() << "Timer ID:" << timerID2;
            break;
        case timerID3:
            qDebug() << "Timer ID:" << timerID3;
            break;
      }
      qDebug() << "Timer ID:" << id ;
  }

2.可以在类中添加一个QTimer类型的成员,这样我们就可以通过信号与槽机制类实现相应的功能,举例如下:

      QTimer *timer = new QTimer(this);
      connect(timer, SIGNAL(timeout()), this, SLOT(update()));
      timer->start(1000);

我们可以使用QTimer中的槽函数start()来开启定时器,设置发出timerEvent事件的时间间隔,或者不设置:

void start(int msec);
void start();

使用stop()来停止定时器,设置时间间隔的第二个方式是调用setInterval()函数:

void setInterval(int msec);

调用setTimerType()设置定时器的精度:

void setTimerType(Qt::TimerType atype);

上述两种方法有两个函数都用到了Qt::TimerType类型的参数,下面详细介绍
int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);

void QTimer::setTimerType(Qt::TimerType atype);

Qt Assitant中的原文如下:

enum Qt::TimerType

The timer type indicates how accurate a timer can be.
 

Constant

Value Description
Qt::PreciseTimer 0 Precise timers try to keep millisecond accuracy
Qt::CoarseTimer 1 Coarse timers try to keep accuracy within 5% of the desired interval
Qt::VeryCoarseTimer 2 Very coarse timers only keep full second accuracy

On UNIX (including Linux, macOS, and iOS), Qt will keep millisecond accuracy for Qt::PreciseTimer. For Qt::CoarseTimer, the interval will be adjusted up to 5% to align the timer with other timers that are expected to fire at or around the same time. The objective is to make most timers wake up at the same time, thereby reducing CPU wakeups and power consumption.

On Windows, Qt will use Windows's Multimedia timer facility (if available) for Qt::PreciseTimer and normal Windows timers for Qt::CoarseTimer and Qt::VeryCoarseTimer.

On all platforms, the interval for Qt::VeryCoarseTimer is rounded to the nearest full second (e.g. an interval of 23500ms will be rounded to 24000ms, and 20300ms to 20000ms).

可见这个参数和定时器的精度有关,上述使用定时器的两种方式中其精度默认都是Qt::CoarseTimer,我大致解释一下上述含义:

在类UNIX系统中,Qt使用Qt::PreciseTimer来保持毫秒级精度(精度偏差最多1毫秒),对于Qt::CoarseTimer,实际间隔时间将会比配置间隔时间多或者少5%,以使得此定时器和其他想要在同一时刻或者临近时刻产生动作的定时器 相结合,那么cpu只需要一次,就可以唤醒这一堆定时器,从而减少cpu的唤醒次数和功耗,如果在使用Qt::PreciseTimer的时候,这一堆定时器可能需要CPU分别去唤醒,那么,功耗也会增加。(本人拙见,仅供参考,勿信以为真)

在windows平台,如果允许的话Qt将使用多媒体定时器来完成Qt::PreciseTimer的要求,使用常规Windows定时器来应对Qt::Coarse和Qt::VeryCoarseTimer。

在所有平台上,Qt::verycoarseTimer参数将会把interval参数的四舍五入成整秒的形式,即第三位全为0.

猜你喜欢

转载自blog.csdn.net/u014453443/article/details/88662035
今日推荐