2012-04-19 66 views

回答

2

你是什麼意思「與模型互動」?如果你的意思是你想通過直接操作來從多個線程訪問模型,那麼你必須序列化訪問模型。由於模型中有很多方法,我建議你不要在模型中添加互斥體 - 它會非常單調乏味,容易出錯,因爲它太容易忘記互斥鎖。相反,請使用模型繼承QObject的事實,從而可以接受事件。

  1. 您的GUI線程直接訪問模式。
  2. 其他線程通過向它發佈事件(也許接收回復事件)與模型進行交互。
  3. gui線程將以任何其他訪問方式連續處理這些事件,從而保護您的模型免受併發訪問。

其他線程當然可以從模型中收到回覆 - 也通過事件。您將有兩個事件基類:一個Request類用於從模型請求事物,然後將有一個模型用於回覆的事件基類。 Request類應該有一個QObject* sender成員,以便模型知道發送回覆事件的QObject。您可能希望請求和回覆都攜帶相同的標識符(比如說連續增加int),以便請求和響應可以匹配。

您必須實現所有未通過重新實現QThread::run()通過事件模型交互的線程代碼,而是一個QObject內。在實例化QObject後,只需將其移至單獨的線程即可。 QThread的默認實現run()將旋轉一個事件循環,以便在有任何事件,信號或定時器準備好時繼續執行QObject。零持續時間定時器是保持線程永久繁忙的一種方式,但要確保一次不會做太多處理,否則會延遲處理傳入事件。

您還可以使用信號和槽,但你不能直接給他們打電話,你只能:

  1. connect()他們,
  2. 通過QMetaObject::invokeMethod調用他們Qt::QueuedConnection
  3. 通過在主線程上下文中執行的仿函數(例如lambda)來調用它們;見this answer如何做到這一點。

場景中,當您的信號連接到駐留在單獨的線程的QObject的槽後面,Qt的創建警每個信號的連接成QMetaCallEvent,然後解編它在螺紋其中QObject的與目標插槽生活。

相關問題