簡體   English   中英

如何退出工作線程QThread的事件循環

[英]How to quit the event loop of a worker QThread

我正在編寫一個帶有按鈕的應用程序,以啟動/停止工作線程(實現QThread )。 輔助線程每隔幾毫秒就不斷調度作業。 要終止工作線程,我從GUI線程調用worker.quit()worker.exit(0)也不起作用)方法,並等待finished信號被激發。

問題在於,即使觸發了finished信號,線程也不會終止。

這是一個最小的示例: https : //gist.github.com/NawfelBgh/941babdc011f07aa4ab61570d7b88f08

最小示例的屏幕截圖

編輯

我對發生的情況的解釋是錯誤的: 工作線程正在終止,但是iter方法正在主線程中執行,如@ sergey-tachenov所說,並通過使用代碼生成的日志記錄進行了確認:

void run() {
    std::cout <<"From worker thread: "<<QThread::currentThreadId() << std::endl;
...
void iter() {
    std::cout <<"From thread: "<<QThread::currentThreadId() << std::endl;
...
void MainWindow::on_pushButton_clicked()
{
    std::cout <<"From main thread: "<<QThread::currentThreadId() << std::endl;

我切換到不依賴QTimer其他設計 但是我沒有將其提交為答案,因為該問題的標題是“如何退出工作者QThread的事件循環”。

線程終止。 只有定時器不在您啟動的線程中運行,而是在主線程中運行,這就是為什么它不會停止的原因。 這是因為默認情況下它使用排隊連接,並且線程對象位於創建它的線程中,該線程是主線程。 要解決這個問題:

  • 不要繼承QThread 除非您想實際擴展QThread的功能,否則通常是一個壞主意。
  • 創建一個繼承QObject的單獨的工作程序對象。
  • 使用moveToThread將工作對象移動到創建的線程。 這將導致其所有插槽實際上在線程中觸發。 如果您使用默認或排隊連接,那就是。

QThread文檔提供了一個很好的例子(第一個)。

請注意,如果您實際上想使用線程提供的數據來更新GUI,則必須以某種方式正確地將該數據發布到GUI線程(可能使用emit和排隊連接),而不是嘗試直接從線程中更新GUI。 而且,如果您要訪問共享數據,則可能需要使用QMutex保護它,而不是像使用共享計數器那樣。

暫無
暫無

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

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