2014-07-22 178 views
2

我有一個子類MyClass,它繼承自QThread如何正確刪除並終止QThread

我創建像這樣與父母到MainWindow實例(本):

mMyClass = new MyClass("some_value", 1, 5L, this); 

我與對象刪除如何Qt的交易的理解是,每一個QObject,其中有一個父被刪除時,父被刪除。

如果我的程序沒有完成,我得到一個警告QThread: Destroyed while thread is still running

如何解決這一個?我在MainWindow的解構器中用下面的代碼試了一下。不幸的是它不能正常工作:

if (mMyClass != 0 && mMyClass->isRunning()) { 
    mMyClass->deleteLater(); 
    mMyClass->quit(); 
    mMyClass->wait(); 
} 
+0

wait()返回什麼?你的線程是否啓動了一個事件循環?也就是說,你在'run()'的實現中調用exec()嗎? –

+0

我不會調用'exec'。 wait()不返回任何東西。 – Niklas

回答

13

你還沒有指定你使用的是什麼版本的Qt,所以我假設5.3。

而且,我相信,在你的線程代碼,你有某種形式的類似下面的無限循環:

while (1) { 
    // do something here. 
} 

首先,最好是在創建後的線程deleteLater()插槽連接至finished()信號線程:

mMyClass = new MyClass("some_value", 1, 5L, this); 
connect(mMyClass, SIGNAL(finished()), mMyClass, SLOT(deleteLater())); 

這將導致該線程在線程完成其作業後儘快由其父代刪除。

現在,爲了完成這個工作,Qt 5.2引入了方法QThread::requestInterruption()QThread::isInterruptionRequested()。您可以使用這些方法告訴你的線程有這樣的代碼來完成:

在主類中退出代碼:

if (mMyClass != 0 && mMyClass->isRunning()) { 
    mMyClass->requestInterruption(); 
    mMyClass->wait(); 
} 

在你的線程代碼:

while (!this->isInterruptionRequested()) { 
    // do your job here! 
} 

會發生什麼情況是,當調用關閉主窗口的代碼時,它會「中斷」線程(如果它是有效的並且正在運行)。該線程將檢查它是否被中斷並將退出,觸發finished()信號,這將觸發deleteLater()插槽,最後,主窗口將在事件循環或類清除時刪除該類。

查看Qt 5.3 docs瞭解更多詳情。