2012-10-17 14 views
1

對Qt來說是如此新鮮。閱讀wiki和C++ Gui編程書籍,並說他們是QThread的子類。發現這不是現在推薦的方式。Qt線程 - 新途徑驗證請

所以我有一些練習代碼在這裏,我有一些關於如果這是正確的問題。所以我會很感激有人看一看。

所以我創建了一個QThread類作爲私人成員用於移動線程。創建它時,我確保不指定父項。所以我的第一個問題是,這可以嗎?

第二個問題來自m_thread-> quit();我發現我的連接完成不會被髮射,直到我這樣做。那麼這是正確的方法嗎?我讀http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/,看到完成和deleteLater之間的連接在同一個線程,但不是100%確定如果這應該用於退出。

最後,deleteLater的談資,這是否意味着我不需要 刪除m_thread

感謝任何人的時間。

代碼在這裏。簡單的QDialog與按鈕。 worker.cpp

#include "worker.h" 

worker::worker(QObject *parent) : 
    QObject(parent) 
{ 
    stopped = false; 
} 

void worker::setupAndRun() 
{ 
    m_thread = new QThread(); 
    connect(m_thread,SIGNAL(started()),this,SLOT(doWork())); 
    connect(m_thread,SIGNAL(finished()),this,SLOT(onComplete())); 
    connect(m_thread,SIGNAL(finished()),m_thread,SLOT(deleteLater())); 
    this->moveToThread(m_thread); 
    m_thread->start(); 
} 

void worker::doWork() 
{ 

    for(int i = 0; i < 20000; i++) 
    { 
     if (this->stopped) 
      break; 
     qDebug() << i << " : " << Q_FUNC_INFO << m_thread->currentThreadId(); 
    } 
    // --- I think the quit calls the finished signal? 
    m_thread->quit(); 

} 

void worker::onComplete() 
{ 
    qDebug() << Q_FUNC_INFO << "Called " << m_thread->currentThreadId(); 
} 

worker.h

#ifndef WORKER_H 
#define WORKER_H 

#include <QObject> 
#include <QDebug> 
#include <QThread> 

class worker : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit worker(QObject *parent = 0); 
    void setupAndRun(); 
signals: 

public slots: 
    void doWork(); 
    void onComplete(); 
private: 
    // --- The thread that I use to movetothread with. 
    // Is this ok? 
    QThread *m_thread; 
    bool stopped; 
}; 

#endif // WORKER_H 

對話框按鈕

void Dialog::on_pushButton_clicked() 
{ 
    m_worker = new worker(); 
    m_worker->setupAndRun(); 
} 

回答

2

我沒有發現任何東西太多一目瞭然,但一些:

既然m_thread是成員變量,您應該處理它有點不同。您可以在構造函數中將其初始化爲null,並在調用m_thread->quit()後設置m_thread = null,因爲它將在不久之後被刪除,並且不需要懸掛指針。

使用此代碼,您應該將完成的信號連接到m_worker的deleteLater(),因爲看起來沒有其他代碼可以刪除它。您還應該在應用程序退出時處理線程,例如qAddPostRoutine,以便所有線程終止並刪除所有相關對象。

+0

Hi hyde。謝謝回覆。但是,當我將m_worker添加爲父級時,在輸出中運行此代碼後發生崩潰:QThread :: wait:Thread嘗試自動等待 QThread:線程仍在運行時被銷燬 QMutex :: lock中的ASSERT失敗:「內部錯誤,無限等待超時。」,文件線程/ qmutex.cpp,第452行 – smurff1975

+0

好的,如果沒有其他更改,可能是線程對象不能是具有線程關係的QObject的子項它。編輯我的答案,以防萬一,避免錯誤信息... – hyde

+0

謝謝你海德。欣賞你的時間。 – smurff1975