使用QTimer和Eventloop延迟代码执行

时间:2018-06-28 08:41:52

标签: c++ multithreading qt signals qtimer

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

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

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();
    }
}

在那个时候,事件循环似乎并没有阻止该方法的执行。 还有其他方法吗?

2 个答案:

答案 0 :(得分:0)

您的方法看起来不必要复杂。我将执行以下操作:

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()));
}

请注意,我摆脱了while循环,因为计时器递归调用了相同的函数。

答案 1 :(得分:0)

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

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();
    }
}

每次计时器超时,它将在线程上踢generateData函数(因为您将类移至该线程)。计时器将以25 Hz的频率保持脉动,因为它实际上是系统调用(而不是对该线程的活动等待)。在Windows上可能不够准确。

请注意,如果有父母,则不能对此调用moveToThread,请参见QT docs 还要注意,类应该从QObject派生,但是我认为已经是这种情况了,因为您正在connect使用