C++ 使用QTimer和Eventloop延迟代码的执行

C++ 使用QTimer和Eventloop延迟代码的执行,c++,multithreading,qt,signals,qtimer,C++,Multithreading,Qt,Signals,Qtimer,我希望我的程序等待QTimer超时以执行特定的方法。函数在循环中进行一些计算,循环完成后,它应该等待计时器超时,并在计时器事件完成后再次运行 下面是生成线程并将计时器连接到generateData()方法的代码的当前状态。此代码在类的构造函数中执行 timer = new QTimer(0); timer->setTimerType(Qt::PreciseTimer); timer->setInterval(40); //25 frames per second QThread

我希望我的程序等待QTimer超时以执行特定的方法。函数在循环中进行一些计算,循环完成后,它应该等待计时器超时,并在计时器事件完成后再次运行

下面是生成线程并将计时器连接到generateData()方法的代码的当前状态。此代码在类的构造函数中执行

timer = new QTimer(0);
timer->setTimerType(Qt::PreciseTimer);
timer->setInterval(40); //25 frames per second


QThread *thread = new QThread(this);
moveToThread(thread);
timer->moveToThread(thread);

connect(thread, SIGNAL(started()), timer, SLOT(start()));
connect(timer, SIGNAL(timeout()), this, SLOT(timerEvent()));
connect(thread, SIGNAL(started()), this, SLOT(generateData()));
connect(this, SIGNAL(finished()), thread, SLOT(quit()));

thread->start();
方法,该方法应在执行for循环后等待计时器

void Class::generateData() {
    while (1) {
        calculation()
        //do some calculation, which takes around 3-5ms
        QEventLoop loop;
        connect(timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        loop.exec();
    }
}
eventloop似乎没有阻止该方法在该时间内执行。
还有其他方法吗?

您的方法看起来不必要复杂。我会这样做:

void Class::generateData()
{
    // Do calculations.
    for (int i = 0; i<object1->size(); ++i)
    {
      object1->at(i)->test();
    }
    // Wait a little bit and do calculations again.
    QTimer::singleShot(40, this, SLOT(generateData()));
}
void类::generateData()
{
//做计算。
对于(int i=0;isize();++i)
{
object1->at(i)->test();
}
//稍等片刻,然后再次进行计算。
QTimer::singleShot(40,this,SLOT(generateData());
}

请注意,我在循环时去掉了
,因为计时器递归地调用相同的函数。

结合您在其他答案中给出的提示,我认为这就是您要寻找的:

Class::Class(QObject *parent)
{
    timer = new QTimer(0);
    timer->setTimerType(Qt::PreciseTimer);
    timer->setInterval(40); //25 frames per second

    QThread *thread = new QThread(this);
    moveToThread(thread);
    timer->moveToThread(thread);
    this->moveToThread(thread);

    connect(thread, SIGNAL(started()), timer, SLOT(start()));
    connect(timer, SIGNAL(timeout()), this, SLOT(generateData()));
    connect(this, SIGNAL(finished()), timer, SLOT(stop()));
    connect(this, SIGNAL(finished()), thread, SLOT(quit()));

    thread->start();
}

void Class::generateData()
{
    // Do calculations.
    for (int i = 0; i<object1->size(); ++i)
    {
        object1->at(i)->test();
    }
}
Class::Class(QObject*parent)
{
计时器=新的QTimer(0);
定时器->设置定时器类型(Qt::PreciseTimer);
定时器->设置间隔(40);//每秒25帧
QThread*thread=新的QThread(此);
移动到线程(线程);
定时器->移动到线程(线程);
此->移动到线程(线程);
连接(线程、信号(started())、计时器、插槽(start());
连接(计时器、信号(超时())、此、插槽(生成数据());
连接(此、信号(完成())、计时器、插槽(停止());
连接(此、信号(完成()、线程、插槽(退出());
线程->开始();
}
void类::generateData()
{
//做计算。
对于(int i=0;isize();++i)
{
object1->at(i)->test();
}
}
每次计时器超时,它都会在线程上触发generateData函数(因为您将类移动到了该线程)。计时器将保持25 Hz的脉冲,因为它实际上是一个系统调用(而不是该线程上的活动等待)。在Windows上,它可能不够精确

请注意,如果此线程具有父线程,则不能对此调用moveToThread,请参阅
还要注意,类应该从QObject派生,但我认为情况已经如此,因为您正在
connect
ing

提供一个,什么是
object1
object1->at(I)->test()?你不是在寻找吗?我更新了问题,但是计算循环对问题来说并不重要。永远不要这样做。您正在重新进入事件循环。不要这样做。你不必。这种方法的问题是,我失去了计时的精度,因为我等待计算完成,然后启动计时器。但我希望在计时器运行时进行计算,因此至少每40毫秒会准确调用一次事件。在这种情况下,您应该将generateData()连接到timer.timeout()插槽,并可能为您调用moveToThread。Qt为您处理线程边界,因为计算是在计时器超时时开始的,所以您不会遇到同样的问题吧?因为计算需要5毫秒,所以我不会这么做accurate@todayihateprogramming,您可以测量计算时间并调整超时,使其始终为40ms。比如说,如果计算需要5毫秒,您将设置
QTimer::singleShot(40-5,这个,SLOT(generateData()),因此总时间仍为40ms。正如我在回答中所添加的,我认为情况并非如此,因为计时器实际上使用的是一个系统调用,它将独立于线程使用触发
QTimer
可以只是类的一个子类,然后移动类也将移动计时器(它移动所有子类)。将线程移动到自身几乎总是不正确的,当线程是类的子线程时,就是这样做的。其他东西应该拥有这两个。目前线程不是成员,但你是对的,这个解决方案可以有一些调整!