2014-03-14 43 views
0

我試圖啓動一個工作線程的事件循環定時器,但我得到這個錯誤: QObject::startTimer: Timers can only be used with threads started with QThread的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); 
} 

回答

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

@SebastianLange計時器應該位於大部分信號接收者所在的相同線程中。否則,當發射器線程停止時,您將停止收件人線程。 –

+1

是真的。在我的腦海裏出現了一些問題,仍然是單槍匹馬。但儘管如此,如果整個對象位於線程,我不會需要移動計時器居住在此對象給其他線程太... –

0

這種方法對我來說似乎有點危險。通過QObject移動到QThread,你讓線程負責對象的事件(信號,槽,消息等)。然而,當對象被刪除時,線程會在對象本身之前被刪除,這可能會導致一些意外的行爲。

recommended approach是分別實例化線程和對象。

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 
} 
相關問題