Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
QObject::startTimer:计时器只能用于以QThread启动的线程_Qt_Qthread_Qtimer - Fatal编程技术网

QObject::startTimer:计时器只能用于以QThread启动的线程

QObject::startTimer:计时器只能用于以QThread启动的线程,qt,qthread,qtimer,Qt,Qthread,Qtimer,我试图在工作线程的事件循环中启动计时器,但出现以下错误: QObject::startTimer:计时器只能用于以QThread启动的线程 这有什么问题 #include <QObject> #include <QThread> #include <QTimer> class A : public QObject { Q_OBJECT public: A(); private: QThread m_workerThread;

我试图在工作线程的事件循环中启动计时器,但出现以下错误:
QObject::startTimer:计时器只能用于以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);
}
#包括
#包括
#包括
A类:公共质量对象
{
Q_对象
公众:
A();
私人:
QThread m_workerThread;
QTimer m_myTimer;
};
A::A()
{
此->移动到线程(&m_workerThread);
m_myTimer.moveToThread(&m_workerThread);
m_workerThread.start();
m_myTimer.启动(1000);
}

我想我找到了答案,我尝试从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);
}

这种方法对我来说似乎有点危险。通过将
QObject
移动到
QThread
上,可以使线程负责对象的事件(信号、插槽、消息等)。但是,当删除对象时,线程将在对象本身之前删除,这可能会导致一些意外行为


方法是分别实例化线程和对象。

在任何地方初始化计时器,但在线程启动时立即启动(将其连接到信号):


希望这会有所帮助:

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";
}
class ReadYoloResult:public QObject
{
Q_对象
公众:
ReadYoloResult(QObject*parent=0);
void startTimer();
QThread-workerThread;
私人:
QTimer*定时器;
公众时段:
void timerSlot();
};
ReadYoloResult::ReadYoloResult(QObject*父对象)
{
此->移动到线程(&workerThread);
计时器=新的QTimer();
连接(定时器,信号(timeout()),此,插槽(timerSlot());
workerThread.start();
//定时器->启动(1000);
}
void ReadYoloResult::startTimer(){
定时器->启动(100);
}
void ReadYoloResult::timerSlot(){

qDebug()@SebastianRange计时器应该在其大多数信号接收器所在的相同线程中。否则,当发射器线程暂停时,您将暂停接收器线程。是的。只是在我脑海中出现了一些错误,仍然是单次触发。但是,如果整个对象都位于线程中,我将不需要移动驻留在该线程中的计时器对象也指向另一个线程…@SebastianLange你的意思是当QTimer成员改为QTimer*时,我添加了一个类似sl_init()的插槽,在其中分配“new QTimer(this)”?我想你是对的,但是你有更多的代码。我更喜欢更少的代码。
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";
}