Qt实现高精度定时器

2022-11-13 14:11:40 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);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章