gpt4 book ai didi

c++ - Qt中实现精确定时器

转载 作者:太空狗 更新时间:2023-10-29 23:07:37 25 4
gpt4 key购买 nike

因为我需要一个比 Qt 更精确的计时器,分辨率约为 15 毫秒,所以我尝试使用 Windows api 中的 QueryPerformanceCounter() 来实现我自己的计时器。

我的第一个目标是从 QObject 继承并构建一个带有无限循环的计时器,每秒触发一个信号。我尝试使用 moveToThread() 将这个计时器移动到它自己的线程,这样它就会每秒更新我的主窗口而不是阻塞整个事情。但是,主窗口永远不会出现,删除无限循环 -> 主窗口出现。

于是尝试了singleshot的方式,基本思路是:

 connect( highPerformanceTimer, SIGNAL(timer_tick()), this, SLOT(timeOutSlot()) );
connect( this, SIGNAL(graphics_updated()), highPerformanceTimer, SLOT(timer_start()));

因此,计时器滴答作响,ui (opengl) 得到更新,在更新结束时生成一个信号以重新启动计时器。

只要我不从 ui 更新代码的末尾删除计时器的重启,我的主窗口仍然不会显示。

在调试器中,我可以看到代码似乎正常工作,它从计时器跳转到 ui 并返回。没有断点会导致突然的段错误。

如果有任何提示可能是问题所在,或者是否有更好的方法在 Qt 中实现它,我将不胜感激。

编辑:更多代码

高性能定时器.h

#ifndef HIGHPERFORMANCETIMER_H
#define HIGHPERFORMANCETIMER_H

#include <QObject>
#include <windows.h>

class HighPerformanceTimer : public QObject
{
Q_OBJECT
public:
HighPerformanceTimer();

signals:
void timer_tick();

public slots:
void timer_start();

private:
// some variables
LARGE_INTEGER highPerformanceCounterValue, highPerformanceCounterFrequency, highPerformanceCounterValueOld;
int interval;
float value;
float last_tick_value;

};

#endif // HIGHPERFORMANCETIMER_H

高性能定时器.cpp

#include "highperformancetimer.h"
#include "windows.h"
#include "QThread"


HighPerformanceTimer::HighPerformanceTimer()
{

QueryPerformanceFrequency(&highPerformanceCounterFrequency);
}



void HighPerformanceTimer::timer_start(){
float i = 0;
// just burn some time
while( i<1000000 ) i++;
emit HighPerformanceTimer::timer_tick();
}

主要 OpenGl 小部件的一些代码:

HighPerformanceTimer *highPerformanceTimer;
protected slots:
virtual void timeOutSlot();

NeHeChapter5( QWidget *parent=0, char *name=0 ) : NeHeWidget( 50, parent, name )
{
highPerformanceTimer = new HighPerformanceTimer();

connect( highPerformanceTimer, SIGNAL(timer_tick()), this, SLOT(timeOutSlot()) );
connect( this, SIGNAL(graphics_updated()), highPerformanceTimer, SLOT(timer_start()));
highPerformanceTimer->moveToThread(&timerThread);
highPerformanceTimer->timer_start();
}

void NeHeChapter5::timeOutSlot(){
timeOut();
}

void NeHeChapter5::timeOut()
{
updateGL();
}

void NeHeChapter5::paintGL()
{
//opengl code *snip*
emit graphics_updated();
}

最佳答案

错误在这里:

NeHeChapter5( QWidget *parent=0, char *name=0 ) : NeHeWidget( 50, parent, name )
{
highPerformanceTimer = new HighPerformanceTimer();

connect( highPerformanceTimer, SIGNAL(timer_tick()), this, SLOT(timeOutSlot()) );
connect( this, SIGNAL(graphics_updated()), highPerformanceTimer, SLOT(timer_start()));
highPerformanceTimer->moveToThread(&timerThread);
highPerformanceTimer->timer_start();
}

你调用 timer_start();它是在调用者线程中调用的,而不是在 timerThread 中。另外你甚至没有开始你的线程。首先调用 timerThread.start()。要在你想要的线程中调用你的 timer_start() ,你应该调用

QMetaObject::invokeMethod(highPerformanceTimer, "timer_start", Qt::QueuedConnection);

它将在新启动的线程中调用 timer_start,而不是在调用者线程中。

此外,您不需要使用完全限定名称调用 timer_tick emit HighPerformanceTimer::timer_tick(); 可以替换为 emit timer_tick();

关于c++ - Qt中实现精确定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12284067/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com