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); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
最新评论