添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一般而言,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::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);
                                    QTimer 类提供重复和单次计时器。QTimer 类为计时器提供了一个高级编程接口。要使用它,首先创建一个 QTimer实例,将其 timeout() 信号连接到相应的插槽,然后调用 start()。从那时起,它将以恒定的间隔发出 timeout() 信号。从那时起,每秒调用一次 update() 槽函数。也可以通过调用 setSingleShot(true) 将计时器设置为仅超时一次。在多线程应用程序中,可以在任何具有事件循环的线程中使用 QTimer。
                                    QT 实现倒计时 完整工程 ,精确到 毫秒 ms
    timer = new QTimer();  
    connect( timer, SIGNAL(timeout()), this, SLOT(timerOver()) );
    timer->start( 1 );  //一秒钟后开始触发,然后一m秒一次
                                    从上面数据对比可以发现,都存在时间抖动,但是都有回归。我们常用的window系统是非实时系统,都会存在时间抖动,这个跟系统的性能和电脑任务状态存在一定关系.我使用10毫秒数据发送100000包数据,并且抓包,然后分析时间戳数据,分析每一包与第一包时间差并且减去等差数如图。2 实现高精度定时器我们还可以使用线程加延时的方式来进行,这种方式总体是可以进行把控。第一个配置是高精度配置,try to keep 这个词用的很微妙,试图保持毫秒级别,代码入选。纵坐标单位位秒,整体来看误差很小,但是局部误差还是比较大。.
                                    众所周知,`Qt `的`QTimer`定时的精度,那是稀里糊涂呀,所以在遇到需要高精度定时器的时候,就没法直接只用QTimer定时器了,只能自己搞一个了。今天分享两种方式,一种是利用Win的相关API实现的,也是`Google`来的这里做一下分享吧。一种就是线程了,其实原理很简单,就是一个线程开while,靠睡眠时间来触发信号。
                                    最近需要使用QT5写个上位机串口助手,给嵌入式系统发送指令,时间要求比较短,需要22ms一次数据流。 
在网上查阅资料后发现,QT有两种方法设置定时器: 
1. QObject 
2. QTimer 
当然网上关于怎样使用这两个类的讲解很多,如:http://blog.csdn.net/andy_93/article/details/52776283。然而一个比较尴尬的事情是,这两个定时器对于20m
	3.1	利用事件void timerEvent(QStimerEvent *ev);
	3.2	启动定时器	    startTimer(1000);毫秒单位
	3.3 timerEvent的返回值是定时器的唯一标示,可以和ev->timerid做比较。
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
                                    当前有许多工程实例需要非常准确的毫秒定时器,然而Qt多提供的QTimer定时器优先级较低,所以其准确性不能满足需求,故本人学习widows中的多媒体定时器自定义了一个高性能定时器的类,经过验证该定时器完全满足需要,且精度为1ms级(如果操作系统中安装的软件少)。本定时器经过实际工控项目时间得知10ms完全没问题,1ms没有试验过。经过测试,moveToThread到一个单独的线程去跑精度确实很高,10ms的时候一开始两三千个数据的误差大致在±1,之后就会保持在±0.2,偶尔一个漂移点大概在±0.5左右。
                                    定时器的精度取决于底层操作系统和硬件。绝大多数平台支持精度为1毫秒,尽管定时器的准确性在许多现实世界的情况下和这不相符。
准确性也取决于定时器类型(Qt::TimerType)。对于Qt::PreciseTimer来说,QTimer将试图保持精确度在1毫秒。精确的定时器也从来不会比预计的还要早超时。
对于Qt::CoarseTimer和Qt::VeryCoarseTimer类型,QTi