簡體   English   中英

QThread-使用插槽quit()退出線程

[英]QThread - Using a slot quit() to exit the thread

我想在線程完成運行時通知對象。 但是,我無法使線程正常退出。 我有以下代碼:

Processor.cpp

thread = new QThread;
tw = new ThreadWorker;
connect(tw, SIGNAL(updateStatus(QString)), this, SLOT(statusUpdate(QString)));
tw->doSetup(thread, strDic);
tw->moveToThread(thread);
thread->start();

while(thread->isRunning())
{
}

qDebug() << "Thread Finished";

ThreadWorker.cpp

void ThreadWorker::doSetup(QThread *thread, const string &path)
{
  _strPath = path;
  connect(thread, SIGNAL(started()), this, SLOT(run()));
  connect(this, SIGNAL(finished()), thread, SLOT(quit())); //tried terminate() also
}


void ThreadWorker::run()
{
  DirectorySearch dicSearch;
  vector<string> vecFileList = dicSearch.getFileList(_strPath);
  emit updateStatus("Directory Fetched");
  emit finished();
}

quit()插槽似乎並未停止線程(QThread :: isFinished從不返回true)。 有人能引導我朝正確的方向發展嗎?

(注意:ThreadWorker不繼承自QThread)

假設Processor.cpp在您的主線程中運行, while(thread->isRunning())循環while(thread->isRunning())您的主線程完全捆綁在一起。 這意味着您的應用程序的事件循環無法執行任何處理,因此,例如信號updateStatus()將永遠不會得到處理。 正如評論中提到的那樣,由於QThread對象是由主線程創建的,因此它的信號也不起作用,因為它們還需要主事件循環來完成其工作。 此外,如果您在主線程中等待工作線程執行某項操作,為什么還要使用工作線程呢? :)

嘗試刪除while循環,增加槽workDone()或任何你想將它命名),以Processor.cpp和連接到您的Threadworkerfinished()信號。

我有同樣的問題,找到了答案。 這是我的問題: QThread.wait()函數的用途是什么?

要解決您的問題,您不需要在while循環中運行QCoreApplication :: instance()-> processEvents(),您需要做的是,而不是調用嘗試向其發送信號的quit()。創建線程的事件循環(現在被while循環阻止),您必須直接調用它。

因此,對於您的代碼,刪除以下行:

connect(this, SIGNAL(finished()), thread, SLOT(quit())); //tried terminate() also

而不是:

emit finished();

采用:

this->thread()->quit();

多田...問題解決了。 經驗教訓:不要嘗試通過qt signal-slot機制從工作線程中退出工作線程,因為您的信號不會最終到達預期的位置(您的工作線程的事件循環),但最終會導致創建線程代替。 您永遠不會知道該線程在做什么,以及它的事件循環是否正在運行,無論如何這都不應該與您的工作線程有關……而是直接調用quit。

您可以使用Qt :: DirectConnection:

connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection); 

這將停止線程。

在moveToThread之前,無需執行“ doSetup”功能...,而是在tw的父代上的SINGALS與tw的SLOTS之間設置連接。

我會做4個連接。 首先是ThreadWorker中的run方法。 多數民眾贊成在簡單和自我解釋。

第二個是從完成的信號到下面的第三個SIGNAL連接。 退出線程的信號

第三個信號應該調用線程的terminate()插槽。 當您連接到run方法時,這將有效地關閉事件循環設置(執行start()時會自動調用exec),並且由於run方法不是某種形式的循環,因此將關閉線程而不會出現問題。

第四個是從線程的Terminate()SIGNAL到tw的父代中的SLOT。 如果您想在那時執行某操作,它將在線程死時向您顯示。

您完成了上述連接(如果需要傳遞字符串,將變量添加到run方法和相應的SIGNAL連接中,您將獲得數據),移至線程,啟動線程,然后將SIGNAL附加到運行中方法。 讓它做自己的事。 完成后,它將執行一個完成信號,該信號與另一個與線程終止插槽的信號相關的信號。 這將殺死事件循環並退出線程,將終止的信號推出,以便您可以執行某些操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM