qt事件系统源码-----定时器

qt定时器的使用一般有以下几种方式:

1、直接使用QTimer对象,绑定定时器的timeout信号;

2、使用QTimer的静态方法singleshot方法,产生一个一次性的定时事件

3、在QObject子类中,调用startTimer方法,产生定时器,并在timerEvent方法中实现其处理;

以上三种方法,本质上都是继承QObject类,调用QObject的startTimer,killTimer方法等实现的;

QObject类中定时器相关的方法有:startTimer、killTimer、timerEvent三个方法;

startTimer源码如下:

qt事件系统源码-----定时器_第1张图片

startTimer的实现比较简单,主要是向eventDispatcher中注册定时器事件;QAbstractEventDispatcher中registerTimer的实现如下:

生成一个定时器的id,并调用派生类的registerTimer的函数;

qt事件系统源码-----定时器_第2张图片

 将定时器相关信息保存在WinTimerInfo结构中,并调用QEventDispatcherWin32Private类中的registerTimer方法;

qt事件系统源码-----定时器_第3张图片

 首先会重新计算定时的时间间隔,调用calculateNextTimeout方法;

qt事件系统源码-----定时器_第4张图片

如果是非常粗糙的定时方式或者定时时间超过2s,且定时器类型不是精确定时,则定时器的触发时间存在500ms左右的偏差;

QZeroTimerEvent事件

如果定时时间间隔为0ms,则会调用qt的postEvent方法,向QEventDispatcherwin32对象抛一个QZeroTimerEvent事件,切入到qt的事件循环中;通过上几节介绍可知,通过postEvent抛出的事件最终会进入到qt_internal_proc方法中;

qt事件系统源码-----定时器_第5张图片

 最终会进入到q->sendPostedEvents()方法中,

qt事件系统源码-----定时器_第6张图片

几经周转,会进入到QEventDispatcherWin32的event方法中,此处是ZeroTimerEvent事件,会调用QCoreApplication::sendEvent方法,向定时器事件的QObject对象发送一个QTimerEvent事件,从而转入到QObject的event方法中执行;并在此抛出一个QZeroTimerEvent事件;

回到registerTimer方法中:

PreciseTimer事件

如果定时器事件类型为精确定时,会调用windows操作系统的timerSetEvent接口,实现精确定时,定时精度1ms,其对应的回调函数qt_fast_time_proc方法如下:

 其会在回调函数中向QEventDispatcherWin32对象post一个QTimerEvent事件;最终进入到QEventDispatcherWin32的event函数中,调用其sendTimerEvent函数,其定义如下:

qt事件系统源码-----定时器_第7张图片

 在其方法中会调用QCoreApplication的sendEvent函数,最终切入到QObject的event函数中;

VeryCoarseTimer事件

精度要求不高的事件,会调用windows API的setTimer函数,注册一个定时器事件,此事件的回调函数为nullptr,qt会使用windows系统产生的WM_TIMER事件;最终会被qt_internal_proc回调函数捕获到;

qt事件系统源码-----定时器_第8张图片

其会直接调用QEventDispatcherWin32函数的sendTimerEvent方法;其余执行流程同上;

总结:

1、qt定时器会产生3种类型的定时事件 ,QZeroTimerEvent事件、QTimerEvent(PreciseTimer),QTimerEvent(VeryCoarseTimer、CoarseTimer);

2、当定时间隔为0时,会产生QZeroTimerEvent事件,其由QCoreApplication的postEvent方法切入到qt的事件循环中,几经周转在此回到QEventDispatcher类中执行;

3、当定时的精度要求比较高时,可以使用PreciseTimer事件类型,其调用weindowsAPI的timerSetEvent接口实现高精度定时,并在其回调函数中调用postEvent方法切入到qt的事件循环中处理;

4、当定时精度要求不高时,可以使用默认事件类型即VeryCoarseTimer事件类型,其会调用windowsAPI的setTimer接口,并产生WM_TIMER事件,切入到qt的事件循环中;

5、CoarseTimer事件类型,会根据其时间间隔决定产生的是精确定时还是粗糙的定时方式。

你可能感兴趣的:(qt,开发语言)