一般而言,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);
}