開發環境
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後,我發現定時器的精度確實變高了, 。自己測試誤差20毫秒左右,設置定時器爲1ms時。誤差只有1毫秒左右 ,而且會自動補償,誤差不會累加
如果用的非實時操作系統(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()));