Qt高精度定时器

一般而言,Qt有两种使用定时器的方式, QObjectQTimer,对于第一种需要重写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);
}


 

  • 8
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: Qt中的定时器是一种常用的机制,可以用于周期性执行特定的代码块。Qt提供了多种类型的定时器,其中使用 QTimer 类可以使用毫秒级别的定时器,但是这种定时器的最小精度只能达到1ms,而有时候我们需要更高精度定时器。 针对这个问题,我们可以使用 Qt 的 QElapsedTimer 类来实现高精度定时器。QElapsedTimer 类是一个简单易用的高精度计时器,精度可以达到纳秒级别。我们可以利用该类来实现 10ms 定时器实现方法如下: - 使用 QTimer 类创建一个 1ms 定时器,每次到达时间时触发一个 signal。 - 在 signal 的槽函数里,获取当前时间,并使用 QElapsedTimer 类的 elapsed() 方法来计算时间差。 - 根据时间差判断是否已经到达 10ms,如果是,则执行我们需要的代码块。 - 否则,继续等待 1ms 定时器下一次的触发。 下面是对应的示例代码: ```cpp QTimer* timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &MyClass::onTimerTimeout); timer->start(1); QElapsedTimer elapsedTimer; elapsedTimer.start(); void MyClass::onTimerTimeout() { qint64 elapsedTime = elapsedTimer.nsecsElapsed(); if (elapsedTime >= 10000000) { // 10ms // 执行需要的操作 elapsedTimer.restart(); } } ``` 通过上述方法,我们就可以实现高精度定时器,从而尽可能地避免了由于定时器精度不够而引起的问题。 ### 回答2: QT是一种非常实用的跨平台开发框架,提供了许多非常实用的工具类和库,QT高精度10ms定时器就是其中一种。 在QT中,定时器可以用来完成一些需要定时执行的任务,比如轮询什么事件或者周期更新一些数据。而对于有些应用场景需要更高的精度,正是QT高精度10ms定时器发挥作用的时候了。 在使用QT高精度10ms定时器时,我们可以通过QTimer来进行设置和调用。首先,我们需要创建一个QTimer实例,并设置计时器时间间隔为10毫秒。然后,我们将时间间隔与所执行的操作绑定在一起,并启动计时器即可。 在使用QT高精度10ms定时器时,需要注意以下几点: 1. 由于定时器的计时是基于系统时间的,因此应当注意避免程序被其他的系统进程或者线程影响而导致计时器出现偏差。 2. 由于定时器的时间间隔比较短,因此在执行操作时要尽可能保证操作的时间较短,避免出现计时器被卡死的情况。 3. 对于涉及到多线程或者多进程的操作,需要进行合理的处理,避免出现线程安全或者进程冲突的情况。 在实际应用中,QT高精度10ms定时器可以广泛应用于各种类型的应用场景,如定时器更新UI界面、控制机器人轮式运动、音频、视频等等。总的来说,QT高精度10ms定时器可以有效地提高应用程序的性能和精度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值