2013-10-12 111 views
0

我有一個困擾了我很長一段時間的設計問題。基本上我有一個需要很長時間才能執行的函數和一個需要響應和最新的gui。當用戶點擊開始按鈕時,long函數開始在while循環中執行,每次執行後gui都需要更新。Qt線程同步設計

我在想這樣做的最好方法是讓QThread在while循環中運行,並且如果用戶按下開始按鈕,long函數將開始執行。類似以下內容:

class Application : public QThread 
{ 
    void run (void) 
    { 
     while (!mExiting) 
     { 
      if (StartPressed) 
       LongFunction(); 

      // Need to update gui before 
      // running long function again 
     } 
    } 
} 

我想這樣做QMetaObject ::與BlockingQueuedConnection但是調用,當GUI應用程序退出,線程卡住,永不退出。我也嘗試過使用QMutex,但是,gui會變成鎖定狀態,等待鎖定並由長功能使用的互斥鎖。

我在想,有什麼辦法可以在應用程序想要退出時取消BlockingQueuedConnection,或者有其他方法來實現這一點。

回答

1

您近了,但您不需要繼承QThread。相反:

  1. 將您的計算放入QObject的插槽中。

  2. 將其設定的出口標誌到另一個時隙中的代碼(比如說Q_SLOT void finish();

  3. 創建對象的實例。創建QThread的實例。致電myObject->moveToThread(myThread)

  4. 開始線程。

  5. 將gui信號連接到計算對象中的插槽,同樣連接計算對象中指示數據已準備就緒的信號。

  6. 要結束了處理和完成線程,假設gui發送stop()信號,設置以下連接:

    1. connect(gui, SIGNAL(stop()), myObject, SLOT(finish()) - 停止你的計算

    2. connect(gui, SIGNAL(stop()), myObject->thread(), SLOT(quit())) - 結束線程中的事件循環

    3. connect(myObject->thread(), SIGNAL(finished()), myObject->thread(), SLOT(deleteLater()) - 刪除線程時run()方法返回

    你仍然需要刪除myObject大功告成時,從中得到的結果,或者至少你的應用程序退出之前。

警告:如果你從GUI線程做它,myObject->thread()是非零這是一個錯誤delete myObject:你不能刪除比當前線程不同線程關聯的對象。零線程親和力意味着沒有線程聲明對象 - 在我們的例子中,當對象的線程被破壞時。然後任何線程都可以刪除它。

出於同樣的原因,您不能moveToThread有一個父對象。移動的對象可以有孩子,但它本身不能有父母。

+0

這解決了我所有的問題! – Dave