设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间13 现在时间13 缓存数据 风骨神仙籍里人,诗狂酒圣且平生。开元一遇成何事,留得千秋万古名。

风骨神仙籍里人,诗狂酒圣且平生。开元一遇成何事,留得千秋万古名。 -- 杨花落尽子规啼

查看: 1216|回复: 2

Qt实现高精度定时器

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:235
  • 打卡月天数:2
  • 打卡总奖励:3595
  • 最近打卡:2025-07-04 12:03:51
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
447
主题
407
精华
0
金钱
4938
积分
922
注册时间
2023-1-6
最后登录
2025-7-4

发表于 2023-2-13 10:50:30 | 显示全部楼层 |阅读模式
一般而言,Qt有两种使用定时器的方式, QObject和QTimer,对于第一种需要重写timerEvent事件来实现,第二种需要声明一个QTimer的对象或指针,用QTimer::timeout()信号连接槽函数,设置定时器类型mTimer.setTimerType(Qt::PreciseTimer);
115204k3wf55fub8hbmb85.jpeg

第一种即使高精度的定时器,保持毫秒级别;第二种粗计时器尽量将精度保持在所需间隔的5%以内;第三种非常粗糙的计时器只能保持完整的秒精度.
  1. #ifndef BACKENDPROIXY_H
  2. #define BACKENDPROIXY_H
  3.  
  4. #include <QObject>
  5. #include <QTimer>
  6. #include <QTime>
  7.  
  8. class BackendProxy : public QObject
  9. {
  10.     Q_OBJECT
  11. public:
  12.     explicit BackendProxy(QObject *parent = nullptr);
  13.  
  14. signals:
  15. private slots:
  16.     void onTimeOut();
  17. private:
  18.     QTimer mTimer;
  19.     QTime lastTime;
  20.  
  21. };
  22.  
  23. #endif // BACKENDPROIXY_H
复制代码
  1. #include "backendproixy.h"
  2.  
  3. #include <QDebug>
  4.  
  5. BackendProxy::BackendProxy(QObject *parent) : QObject(parent)
  6. {
  7.     connect(&mTimer,&QTimer::timeout,this,&BackendProxy::onTimeOut);
  8.     mTimer.setTimerType(Qt::PreciseTimer);
  9.     mTimer.start(50);
  10. }
  11.  
  12.  
  13. void BackendProxy::onTimeOut()
  14. {
  15.     QTime currentTime;
  16.     int elapsed = 0;
  17.     if(lastTime == QTime()){
  18.         lastTime = QTime::currentTime();
  19.     }else{
  20.         currentTime = QTime::currentTime();
  21.         elapsed = lastTime.msecsTo(currentTime);
  22.         lastTime = QTime::currentTime();
  23.     }
  24.     qDebug()<<"Run.elapsed ="<<elapsed<<"ms";
  25. }
复制代码
下面分别展示三种类型的时间间隔:
Qt::PreciseTimer:
115204xufuful0uztclmll.jpeg

Qt::CoarseTimer:
115204bny4gl4kklncisjs.jpeg

Qt::VeryCoarseTimer:
115205o3c7cp21s3l487p6.jpeg

显而易见,第一种的精度最高,但偶尔也会超过20ms,对于一些实时性较高的通讯来说,还是达不到要求.使用线程加延时能达到最多正负1ms的误差,一下输出我使用的是10ms一个周期:
115205rqbp2961qy8fk7hq.jpeg

现在也贴上代码:
  1. #ifndef PERFORMANCEFREQUENCY_H
  2. #define PERFORMANCEFREQUENCY_H
  3.  
  4. #include<QThread>
  5. #include<QDebug>
  6. #include<QUdpSocket>
  7. #include <QHostAddress>
  8.  
  9.  
  10. #define SEND_TIME 10
  11.  
  12. class PerformanceFrequency : public QThread
  13. {
  14.     Q_OBJECT
  15. public:
  16.     explicit PerformanceFrequency(QObject *parent = nullptr);
  17.     void setThreadRunning(bool start){bRunning = start;}
  18.     void appendByte(QByteArray array);
  19.     void removeOneByte(QByteArray array);
  20. signals:
  21.     void sendJaguarJointControl(QByteArray ba);
  22.     void heartTime(int time);
  23. protected:
  24.     void run() override;
  25. private:
  26.     QList<QByteArray> listByte;
  27.     bool bRunning = true;
  28.  
  29. };
  30.  
  31. #endif // PERFORMANCEFREQUENCY_H
复制代码
  1. #include "performancefrequency.h"
  2. #include <QTime>
  3.  
  4. #include <QMutex>
  5. #include <QMutexLocker>
  6.  
  7. PerformanceFrequency::PerformanceFrequency(QObject *parent)
  8.     : QThread(parent)
  9. {
  10.     QByteArray heart;
  11.     heart[0] = 0xf0;
  12.     heart[1] = heart[2] = heart[3] = heart[4] = heart[5] = heart[6] = heart[7] =  0;
  13.     listByte.append(heart);
  14. }
  15.  
  16. void PerformanceFrequency::run()
  17. {
  18.     while(bRunning){
  19.         QTime startTime = QTime::currentTime();
  20.         msleep(SEND_TIME);
  21.         for(int i = 0;i < listByte.size();i++){
  22.             emit sendJaguarJointControl(listByte.at(i));
  23.         }
  24.  
  25.         QTime stopTime = QTime::currentTime();
  26.         int elapsed = startTime.msecsTo(stopTime);
  27.         emit heartTime(elapsed);
  28.         qDebug()<<"Run.elapsed ="<<elapsed<<"ms";
  29.     }
  30. }
  31.  
  32. void PerformanceFrequency::appendByte(QByteArray array)
  33. {
  34.     static QMutex mutex;
  35.     QMutexLocker locker(&mutex);
  36.     listByte.append(array);
  37. }
  38. void PerformanceFrequency::removeOneByte(QByteArray array)
  39. {
  40.     static QMutex mutex;
  41.     QMutexLocker locker(&mutex);
  42.     listByte.removeOne(array);
  43. }
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持晓枫资讯。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
23
积分
26
注册时间
2022-12-28
最后登录
2022-12-28

发表于 2025-3-19 16:28:57 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:无名新人
  • 打卡总天数:1
  • 打卡月天数:0
  • 打卡总奖励:5
  • 最近打卡:2025-04-20 13:58:02
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
17
积分
4
注册时间
2023-5-28
最后登录
2025-4-20

发表于 5 天前 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表