Qt定时器事件与计数器

时间:2022-06-02 00:14:01

    书上写的定时器事件有两种方法,但是我觉得这两个“方法”并不是一回事。
    一种方法实现的是定时器,而另一种方法实现的是计数器的功能,虽然这两种方法在效果上是一样的,但是从我以前学习硬件、嵌入式的角度看,这两种实现方式是有本质区别的。

1、定时器事件

使用QTimer定时器类
QTimer类提供重复性和单次定时器。

    Header: #include <QTimer>
    qmake: QT += core
    Inherits: QObject

    1、 首先创建一个定时器类的对象,习惯在定义中声明为私有。
    2、 timer 超时后会发出timeout()信号,所以在创建好定时器对象后给其建立信号与槽。
    3、 在需要开启定时器的地方调用QTimer::start ( int msec );毫秒级别。从此以后,它会以固定的时间间隔发出timeout()信号。
    4、 在槽函数里面做超时处理。

Timer=new QTimer(this);
connect(Timer,&QTimer::timeout,this,&TimeOut);
Timer->start(1000);//millisecond
void MainWindow::TimeOut()//定时器事件处理
{
    qDebug()<<"timeout!!";
}

    可以通过调用setSingleShot(true)来设置定时器超时一次。 也可以使用静态QTimer :: singleShot()函数在指定的时间间隔后调用一个插槽:

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

    在多线程应用程序中,可以在任何有事件循环的线程中使用QTimer。 要从非GUI线程启动事件循环,请使用QThread :: exec()。 Qt使用定时器的线程关联来确定哪个线程将发出timeout()信号。 因此,必须在其线程中启动和停止计时器; 从另一个线程启动一个定时器是不可能的。
    作为一种特殊情况,当窗口系统的事件队列中的所有事件都被处理完毕后,超时时间为0的QTimer将超时。 这可以用来做繁重的工作,同时提供一个快速的用户界面:

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

    从此,processOneThing()将被重复调用。 它应该以这样的方式编写,使得它总是快速返回(通常在处理完一个数据项之后),以便Qt可以将事件传递给用户界面,并在完成所有工作后立即停止定时器。 这是在GUI应用程序中执行繁重工作的传统方式,但是随着多线程越来越多地在越来越多的平台上可用,我们预计零毫秒QTimer对象将逐渐被QThreads所取代。

2、计数器触发事件

使用QObject中的定时器,缺点是timerEvent()不支持单次定时器或信号等高级功能。
    1、 int QObject::startTimer ( int interval );
    开启一个定时器,参数interval是毫秒级别。当开启成功后会返回定时器的ID, 每隔interval 时间后会进入timerEvent 函数。
    2、 void QObject::timerEvent ( QTimerEvent * event );
    当定时器计数值溢出后,会进入该事件timerEvent函数,需要重写!!在函数中通过判断event->timerId()来确定定时器,然后执行某个定时器的服务函数。
    3、 void QObject::killTimer ( int id );
    通过从startTimer返回的ID传入killTimer 函数中关闭定时器。

需要#include <QObject>

    void  handleTimeout();  //超时处理函数 
    virtual void timerEvent( QTimerEvent *event);  
private:  
    int TimerID;  
#include <QTimerEvent>  
MyTimer::MyTimer(QObject *parent)  
    :QObject(parent)  
{  
    TimerID = this->startTimer(1000);  
}  
void MyTimer::timerEvent(QTimerEvent *event)  
{  
    if(event->timerId() == TimerID){  
        handleTimeout();  
    }  
}    
void MyTimer::handleTimeout()  
{   
    killTimer(TimerID);  
}  

3、QBasicTimer

    另一种实现方式是QBasicTimer。 通常不比直接使用QObject :: startTimer()麻烦。 有关这三种方法的概述,参阅Qt助手。