Qt定時器的應用及精度設置

開發環境
Windows 10 企業版
Qt 5.9.7+MinGW
衆所周知,在Qt中有兩個方法可以實現定時器,一個是用QTimer類,另一個是用QObject的定時器事件。(關於QTimer類和QObject的定時器事件的介紹與使用,大家可以自行找資料)

我在開發過程中遇到的問題是:記錄過程中,數據丟失(不管是用QTimer類還是QObject的定時器事件)。後來我把記錄的時間打印出來,發現每次進入定時器的處理函數時,時間都比原來的加了10+毫秒。所以應該是定時器的精度不滿足要求。後來,我查看資料,發現在Qt的定時器中有3種精度,分別是:

常量 描述
Qt::PreciseTimer 0 精確的定時器,儘量保持毫秒精度。
Qt::CoarseTimer 1 粗略的定時器,儘量保持精度在所需的時間間隔5%範圍內。
Qt::VeryCoarseTimer 2 很粗略的定時器,只保留完整的第二精度。

而QTimer和QObject的定時器事件的默認精度類型都是Qt::CoarseTimer。所以爲了提高定時器的精度,我們需要設置定時器的精度。設置方法如下:
QTimer類,在初始化定時器對象的時候調用setTimerType(Qt::TimerType atype)函數,即setTimerType(Qt::PreciseTimer);
QObject的定時器事件,在調用startTimer()函數的時候,指定定時器的精度,即startTimer(interval, Qt::PreciseTimer);

在把定時器的精度設置爲Qt::PreciseTimer後,我發現定時器的精度確實變高了,誤差只有1毫秒左右 ,而且會自動補償,誤差不會累加 。自己測試誤差20毫秒左右,設置定時器爲1ms時。

如果用的非實時操作系統(Windows、iOS、Android等),不可能做到1ms的精度,因爲操作系統的時間輪詢都得5ms,在Windows操作系統上,非Server版(WinXP/7/8/10)每個子線程的事件輪詢是7~8個時間片(5*5ms),Server版( WinServer2003/2008 )每個子線程的事件輪詢是3~5個時間片。要想用高精度定時(小於15ms),只能用實時操作系統,利用硬件的中斷來做。

代碼:

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
    timer->setTimerType(Qt::PreciseTimer);
    timer->start(1);

執行一次的定時器

QTimer::singleShot(200, this, SLOT(updateCaption()));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章