如何从另一个线程正确停止QTimer

问题描述 投票:0回答:1

我看到这样的话题已经讨论了很多次,但是找不到简单情况的明确答案。我在自己的线程中运行Worker类,在该线程中创建计时器,并由于某种情况希望将其停止。但是我得到了错误:

无法从另一个线程停止计时器

我填补了在Qt中工作的线程缺少一些核心逻辑的情况。有人可以解释如何解决吗?谢谢。

这里是main.cpp

#include <QCoreApplication>
#include <QObject>
#include <QtDebug>

#include "worker.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Worker w;

    return a.exec();
}

Worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QTimer>
#include <QThread>
#include <QtDebug>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);
private:
    QThread t;
    QTimer *timer;

    int count = 1;

public slots:

    void dataTimerFunction();
    void onStopTimer(QTimer *t);
signals:
    void stopTimer(QTimer *t);
};

#endif // WORKER_H

Worker.cpp

#include "worker.h"

Worker::Worker(QObject *parent) : QObject(parent)
{
    this->moveToThread(&t);
    QObject::connect(&t, &QThread::finished, this, &QObject::deleteLater);

    t.start();

    // are we in the new thread from this point, right?
    timer = new QTimer();
    QObject::connect(timer, &QTimer::timeout, this, &Worker::dataTimerFunction);
    QObject::connect(this, &Worker::stopTimer, this, &Worker::onStopTimer);
    // QObject::connect(this, &Worker::stopTimer, this, &Worker::onStopTimer, Qt::QueuedConnection);  doesn't work as well
    timer->start(200);
}

void Worker::dataTimerFunction()
{
    qDebug()<<count;
    count++;
    if (count>5){
        emit stopTimer(timer);
        //timer->stop();
    }
}

void Worker::onStopTimer(QTimer *t)
{
    t->stop();
}
qt qthread qtimer
1个回答
0
投票

问题确实是计时器未移至您的线程。

这里是经过修改的工作者类,可以完成您想要实现的目标。它将计时器也移动到线程,然后通过使用信号/插槽启动和停止它。

worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QTimer>
#include <QThread>
#include <QtDebug>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);
private:
    QThread t;
    QTimer *timer;

    int count = 1;

signals:
    void stopTimer();
    void startTimer(int msec);

public slots:

    void dataTimerFunction();
};

#endif // WORKER_H

worker.cpp

#include "worker.h"

Worker::Worker(QObject *parent) : QObject(parent)
{
    // are we in the new thread from this point, right?
    timer = new QTimer(nullptr);

    this->moveToThread(&t);
    timer->moveToThread(&t);
    QObject::connect(&t, &QThread::finished, this, &QObject::deleteLater);
    t.start();

    QObject::connect(timer, &QTimer::timeout, this, &Worker::dataTimerFunction);
    QObject::connect(this, &Worker::stopTimer, timer, &QTimer::stop, Qt::QueuedConnection);  
    QObject::connect(this, &Worker::startTimer, timer, static_cast<void (QTimer::*)(int)>(&QTimer::start), Qt::QueuedConnection);  
    startTimer(200);
}



void Worker::dataTimerFunction()
{
    qDebug()<<count;
    count++;
    if (count>5){
        stopTimer();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.