我正在尝试在工作线程的事件循环中启动一个Timer,但是我收到此错误:
QObject::startTimer: Timers can only be used with threads started with QThread
这有什么不对吗?
#include <QObject>
#include <QThread>
#include <QTimer>
class A : public QObject
{
Q_OBJECT
public:
A();
private:
QThread m_workerThread;
QTimer m_myTimer;
};
A::A()
{
this->moveToThread(&m_workerThread);
m_myTimer.moveToThread(&m_workerThread);
m_workerThread.start();
m_myTimer.start(1000);
}
答案 0 :(得分:1)
我想我想通了,我试图从GUI线程启动计时器,在我将它移动到工作线程之后,这种方式似乎有效:
class A : public QObject
{
Q_OBJECT
public:
A();
private:
QThread m_workerThread;
QTimer m_myTimer;
public slots:
void sl_startTimer();
};
A::A()
{
this->moveToThread(&m_workerThread);
m_myTimer.moveToThread(&m_workerThread);
m_workerThread.start();
QMetaObject::invokeMethod(this, "sl_startTimer", Qt::QueuedConnection);
}
void A::sl_startTimer()
{
m_myTimer.start(1000);
}
答案 1 :(得分:1)
在任何地方初始化您的计时器,但在线程启动时将其启动(将其附加到QThread::started信号):
class A : public QObject
{
Q_OBJECT
public:
A();
private slots:
void started();
void timeout();
private:
QThread m_workerThread;
QTimer m_myTimer;
};
A::A()
{
moveToThread(&m_workerThread);
connect(&m_workerThread, SIGNAL(started()), this, SLOT(started()));
connect(&m_myTimer, SIGNAL(timeout()), this, SLOT(timeout()));
m_myTimer.setInterval(1000);
m_myTimer.moveToThread(&m_workerThread);
m_workerThread.start();
}
void A::started()
{
timer.start();
}
void A::timeout()
{
// timer handler
}
答案 2 :(得分:0)
这种方法对我来说似乎有点危险。通过将QObject
移动到QThread
,您将使线程负责对象的事件(信号,槽,消息等)。但是,当删除对象时,线程将在对象本身之前被删除,这可能会导致一些意外的行为。
recommended approach是分别实例化线程和对象。
答案 3 :(得分:0)
希望这会有所帮助:
class ReadYoloResult : public QObject
{
Q_OBJECT
public:
ReadYoloResult(QObject *parent = 0);
void startTimer();
QThread workerThread;
private:
QTimer *timer;
public slots:
void timerSlot();
};
ReadYoloResult::ReadYoloResult(QObject * parent)
{
this->moveToThread(&workerThread);
timer = new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(timerSlot()));
workerThread.start();
//timer->start(1000);
}
void ReadYoloResult::startTimer(){
timer->start(100);
}
void ReadYoloResult::timerSlot(){
qDebug()<<"In timer slot";
}