Qt精确定时器计时精度

Posted

技术标签:

【中文标题】Qt精确定时器计时精度【英文标题】:Qt precise timer timing accuracy 【发布时间】:2019-03-14 17:30:19 【问题描述】:

我编写了一个简单的演示来检查单次计时器的准确性。以下是我的代码:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);

    //two singleshot timers  
    QTimer::singleShot(1000,Qt::PreciseTimer,this,SLOT(myslot1()));
    QTimer::singleShot(10000,Qt::PreciseTimer,this,SLOT(myslot2()));

    //metrics of timing accuraccy
    t = 0;
    timer = new QTimer();
    timer->setInterval(100);
    timer->setTimerType(Qt::PreciseTimer);
    connect(timer,SIGNAL(timeout()),this,SLOT(timerhandler()),Qt::DirectConnection);
    timer->start();


void MainWindow::myslot1()

    qDebug()<<"myslot1 called: t="<<100*t;
    ui->lcdNumber1->display(1);


void MainWindow::myslot2()

    qDebug()<<"myslot2 called: t="<<100*t;
    ui->lcdNumber2->display(2);


void MainWindow::timerhandler()

    t++;
    ui->lcdNumber->display(t*100);

运行这些代码给出:

myslot1 called: t= 900
myslot2 called: t= 9900

在我看来,精确计时器的计时误差约为 100 毫秒。我说的对吗??明显的错误是由于我为timer 设置的时间间隔造成的吗?根据一些帖子 (QTimer not accurate at all?),QTimer 可能根本不那么准确。

【问题讨论】:

您的时间是使用QTimer(变量timer)测量的,该变量被明确配置为间隔为100 毫秒——所以我不确定您还有什么期望。抱歉,如果我遗漏了什么。 尝试将调试打印也添加到 timerhandler。此外,使用 QElapsedTimer (所有相同,在构造函数中重置)在调试打印中打印时间戳。我认为这应该澄清一些事情,特别是关于插槽被调用的时间和时间点。 QTimer 并不是为了实现时钟。如果你需要一个时钟,即测量挂钟时间的东西,或者它的流逝(秒表),那么你就会忘记 QTimer 的存在,一切都会好起来的:在这种情况下,它只是一种干扰。跨度> 【参考方案1】:

如果你想要两个事件之间的时间,你必须使用QElapsedTimer:

例子:

#include <QtCore>

class Foo: public QObject

    Q_OBJECT
public:
    Foo(QObject *parent=nullptr):
        QObject(parent),
        timer(new QTimer())
    
        QTimer::singleShot(1000,Qt::PreciseTimer,this, &Foo::myslot1);
        QTimer::singleShot(10000,Qt::PreciseTimer,this, &Foo::myslot2);

        timer->setInterval(100);
        timer->setTimerType(Qt::PreciseTimer);
        connect(timer,&QTimer::timeout,this,&Foo::timerhandler,Qt::DirectConnection);
        timer->start();

        timer_measure.start();
    
private:
    Q_SLOT void myslot1()
        qDebug()<< __PRETTY_FUNCTION__ << timer_measure.elapsed();
    
    Q_SLOT void myslot2()
        qDebug()<< __PRETTY_FUNCTION__ << timer_measure.elapsed();
    
    void timerhandler()
    
        qDebug()<< __PRETTY_FUNCTION__ << timer_measure.elapsed();
    
    QElapsedTimer timer_measure;
    QTimer *timer;
;

int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);
    Foo foo;
    return a.exec();

#include "main.moc"

输出:

void Foo::timerhandler() 100
void Foo::timerhandler() 200
void Foo::timerhandler() 301
void Foo::timerhandler() 400
void Foo::timerhandler() 500
void Foo::timerhandler() 600
void Foo::timerhandler() 700
void Foo::timerhandler() 800
void Foo::timerhandler() 900
void Foo::myslot1() 1000
void Foo::timerhandler() 1001
void Foo::timerhandler() 1100
void Foo::timerhandler() 1200
void Foo::timerhandler() 1300
void Foo::timerhandler() 1401
void Foo::timerhandler() 1500
void Foo::timerhandler() 1600
void Foo::timerhandler() 1700
void Foo::timerhandler() 1801
void Foo::timerhandler() 1900
void Foo::timerhandler() 2000
void Foo::timerhandler() 2100
void Foo::timerhandler() 2201
void Foo::timerhandler() 2300
void Foo::timerhandler() 2400
void Foo::timerhandler() 2500
void Foo::timerhandler() 2600
void Foo::timerhandler() 2700
void Foo::timerhandler() 2800
void Foo::timerhandler() 2901
void Foo::timerhandler() 3000
void Foo::timerhandler() 3100
void Foo::timerhandler() 3200
void Foo::timerhandler() 3301
void Foo::timerhandler() 3400
void Foo::timerhandler() 3500
void Foo::timerhandler() 3600
void Foo::timerhandler() 3701
void Foo::timerhandler() 3800
void Foo::timerhandler() 3900
void Foo::timerhandler() 4000
void Foo::timerhandler() 4101
void Foo::timerhandler() 4200
void Foo::timerhandler() 4300
void Foo::timerhandler() 4400
void Foo::timerhandler() 4501
void Foo::timerhandler() 4600
void Foo::timerhandler() 4700
void Foo::timerhandler() 4800
void Foo::timerhandler() 4901
void Foo::timerhandler() 5000
void Foo::timerhandler() 5100
void Foo::timerhandler() 5200
void Foo::timerhandler() 5300
void Foo::timerhandler() 5400
void Foo::timerhandler() 5500
...

【讨论】:

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

Qt 精确定时器

Qt 精确定时器

C#下利用高精度计时器进行计时操作

C++ / Qt 减少循环频率

VC中如何获取当前时间(精度达到毫秒级)

C++ 跨平台高分辨率计时器