Qt 精确定时器

Posted DreamLife.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 精确定时器相关的知识,希望对你有一定的参考价值。

Qt 精确定时器

文章目录


关键字: Qt定时器Qtimer线程精度

摘要

众所周知,Qt QTimer定时的精度,那是稀里糊涂呀,所以在遇到需要高精度的定时器的时候,就没法直接只用QTimer定时器了,只能自己搞一个了。今天分享两种方式,一种是利用Win的相关API实现的,也是Google来的这里做一下分享吧。一种就是线程了,其实原理很简单,就是一个线程开while,靠睡眠时间来触发信号。

1 QTimer 定时器类型选择

其实QTimer定时器也是有进度可以选着的。官网描述如下,如果可以接受的话,其实可以通过定时器类型来确定,包括我后期使用中,其实大部分还是使用了Qt的官方定时器。

enum Qt::TimerType

The timer type indicates how accurate a timer can be.

ConstantValueDescription
Qt::PreciseTimer0Precise timers try to keep millisecond accuracy
Qt::CoarseTimer1Coarse timers try to keep accuracy within 5% of the desired interval
Qt::VeryCoarseTimer2Very coarse timers only keep full second accuracy

On UNIX (including Linux, macOS, and ios), Qt will keep millisecond accuracy for Qt::PreciseTimer. For Qt::CoarseTimer, the interval will be adjusted up to 5% to align the timer with other timers that are expected to fire at or around the same time. The objective is to make most timers wake up at the same time, thereby reducing CPU wakeups and power consumption.

On Windows, Qt will use Windows’s Multimedia timer facility (if available) for Qt::PreciseTimer and normal Windows timers for Qt::CoarseTimer and Qt::VeryCoarseTimer.

On all platforms, the interval for Qt::VeryCoarseTimer is rounded to the nearest full second (e.g. an interval of 23500ms will be rounded to 24000ms, and 20300ms to 20000ms).

Qt::PreciseTimer 毫米级高精度定时器

Qt::CoarseTimer 粗略计时器,进度控制在5%以内

Qt::VeryCoarseTimer 非常粗糙的定时器,这个基本是个废废吧

2 第一种精确定时器

这个就是参考Windows下多媒体定时器为改造的一个高性能定时器。弊端呢就是,这个是没法夸平台的

Pro中添加一下代码

LIBS += -lwinmm

这里就直接上代码

#ifndef TURING_WIN_PERFORMANCETIMER_H
#define TURING_WIN_PERFORMANCETIMER_H

#include <QObject>

#include "windows.h"
/**
 * @brief The Turing_Win_PerformanceTimer class
 * Win平台下,高精度毫秒级定时器
 * 这里使用了win的api,所以在linux下无法使用
 */
class Turing_Win_PerformanceTimer : public QObject

    Q_OBJECT
public:
    explicit Turing_Win_PerformanceTimer(QObject *parent = nullptr);
    ~Turing_Win_PerformanceTimer();

signals:
    void timeout();
public slots:
    void start(int timeInterval);
    void stop();
    friend WINAPI void  CALLBACK PeriodCycle(uint,uint,DWORD_PTR,DWORD_PTR,DWORD_PTR);
private:
    int m_interval;
    int m_id;

;

#endif // TURING_WIN_PERFORMANCETIMER_H
#include "turing_win_performancetimer.h"




#ifdef __MINGW32__
#define TIME_KILL_SYNCHRONOUS 0x0100
#endif

Turing_Win_PerformanceTimer::Turing_Win_PerformanceTimer(QObject *parent)
    : QObjectparent

    m_id=0;


Turing_Win_PerformanceTimer::~Turing_Win_PerformanceTimer()

    stop();

void  CALLBACK PeriodCycle(uint timerId,uint,DWORD_PTR user,DWORD_PTR,DWORD_PTR)

    Q_UNUSED(timerId)
    Turing_Win_PerformanceTimer *t=reinterpret_cast<Turing_Win_PerformanceTimer *>(user);
    emit t->timeout();

void Turing_Win_PerformanceTimer::start(int timeInterval)

    m_id = timeSetEvent(timeInterval,1,PeriodCycle,(DWORD_PTR)this,TIME_CALLBACK_FUNCTION|TIME_PERIODIC|TIME_KILL_SYNCHRONOUS);

void Turing_Win_PerformanceTimer::stop()

    if(m_id)
    
        timeKillEvent(m_id);
        m_id=0;
    



3 第二种线程定时器

这里也直接上代码,这种感觉有点浪费资源。

class SpeedThread :  public QThread

    Q_OBJECT
public:
    /**
     * @brief run
     * 重载线程函数
     */
    virtual void run();
signals:
    void signalselfInspection(int number);
    void signalSelfInspectionfinished();
public:
    bool runFlag = true;
private:
    int m_number = 0;
    bool flagDESC = false;

;
void SpeedThread::run()

    while (runFlag)
    
        emit signalselfInspection(m_number);
        if(flagDESC)
        
            if(m_number == 0)
            
                runFlag = !runFlag;
                flagDESC = !flagDESC;
                emit signalSelfInspectionfinished();
            
            m_number--;
        
        else
        
            m_number++;
            if(m_number == 100)
            
                flagDESC = !flagDESC;
            
        
        msleep(8);
    


以上是关于Qt 精确定时器的主要内容,如果未能解决你的问题,请参考以下文章

Qt精确定时器计时精度

Qt学习 之 定时器

Qt中两种定时器用法

Qt中使用定时器(可使用QObject::timerEvent定时执行,QTimer::singleShot可只触发一次)

Qt中定时器使用的两种方法

Qt中定时器使用的两种方法