Qt實現高精度定時器
一般而言,Qt有兩種使用定時器的方式, QObject和QTimer,對於第一種需要重寫timerEvent事件來實現,第二種需要聲明一個QTimer的對象或指針,用QTimer::timeout()信號連接槽函數,設置定時器類型mTimer.setTimerType(Qt::PreciseTimer);
第一種即使高精度的定時器,保持毫秒級別;第二種粗計時器盡量將精度保持在所需間隔的5%以內;第三種非常粗糙的計時器隻能保持完整的秒精度.
#ifndef BACKENDPROIXY_H #define BACKENDPROIXY_H #include <QObject> #include <QTimer> #include <QTime> class BackendProxy : public QObject { Q_OBJECT public: explicit BackendProxy(QObject *parent = nullptr); signals: private slots: void onTimeOut(); private: QTimer mTimer; QTime lastTime; }; #endif // BACKENDPROIXY_H
#include "backendproixy.h" #include <QDebug> BackendProxy::BackendProxy(QObject *parent) : QObject(parent) { connect(&mTimer,&QTimer::timeout,this,&BackendProxy::onTimeOut); mTimer.setTimerType(Qt::PreciseTimer); mTimer.start(50); } void BackendProxy::onTimeOut() { QTime currentTime; int elapsed = 0; if(lastTime == QTime()){ lastTime = QTime::currentTime(); }else{ currentTime = QTime::currentTime(); elapsed = lastTime.msecsTo(currentTime); lastTime = QTime::currentTime(); } qDebug()<<"Run.elapsed ="<<elapsed<<"ms"; }
下面分別展示三種類型的時間間隔:
Qt::PreciseTimer:
Qt::CoarseTimer:
Qt::VeryCoarseTimer:
顯而易見,第一種的精度最高,但偶爾也會超過20ms,對於一些實時性較高的通訊來說,還是達不到要求.使用線程加延時能達到最多正負1ms的誤差,一下輸出我使用的是10ms一個周期:
現在也貼上代碼:
#ifndef PERFORMANCEFREQUENCY_H #define PERFORMANCEFREQUENCY_H #include<QThread> #include<QDebug> #include<QUdpSocket> #include <QHostAddress> #define SEND_TIME 10 class PerformanceFrequency : public QThread { Q_OBJECT public: explicit PerformanceFrequency(QObject *parent = nullptr); void setThreadRunning(bool start){bRunning = start;} void appendByte(QByteArray array); void removeOneByte(QByteArray array); signals: void sendJaguarJointControl(QByteArray ba); void heartTime(int time); protected: void run() override; private: QList<QByteArray> listByte; bool bRunning = true; }; #endif // PERFORMANCEFREQUENCY_H
#include "performancefrequency.h" #include <QTime> #include <QMutex> #include <QMutexLocker> PerformanceFrequency::PerformanceFrequency(QObject *parent) : QThread(parent) { QByteArray heart; heart[0] = 0xf0; heart[1] = heart[2] = heart[3] = heart[4] = heart[5] = heart[6] = heart[7] = 0; listByte.append(heart); } void PerformanceFrequency::run() { while(bRunning){ QTime startTime = QTime::currentTime(); msleep(SEND_TIME); for(int i = 0;i < listByte.size();i++){ emit sendJaguarJointControl(listByte.at(i)); } QTime stopTime = QTime::currentTime(); int elapsed = startTime.msecsTo(stopTime); emit heartTime(elapsed); qDebug()<<"Run.elapsed ="<<elapsed<<"ms"; } } void PerformanceFrequency::appendByte(QByteArray array) { static QMutex mutex; QMutexLocker locker(&mutex); listByte.append(array); } void PerformanceFrequency::removeOneByte(QByteArray array) { static QMutex mutex; QMutexLocker locker(&mutex); listByte.removeOne(array); }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。