簡體   English   中英

QThread無法啟動

[英]QThread doesn't start

很抱歉,這篇文章的長度。 但是我現在被困了兩天...

我正在研究通過ActiveX與硬件設備通信的Qt 4.6 Windows應用程序。

當我發送命令時,設備會做一些事情,完成后(可能需要一分鍾)它會發出信號。 我需要等待此信號,以了解一切正常(或不正常)並采取一些措施。

用戶單擊按鈕時,命令會發送到設備。 顯然,我不希望HMI凍結。

我確信我必須使用線程。 因此,我確定了三個線程:

  1. HMI對應的主線程
  2. 硬件控制器(在發送命令並等待信號后鎖定)
  3. 硬件通知偵聽器,該偵聽器不斷從硬件獲取信號並解鎖線程2

這是類圖:

類圖]

還有一個序列圖,顯示我如何看待事物:

順序圖

說明:

當用戶啟動我的應用程序時,將創建HMI。 HMI的構造函數調用Worker的構造函數。 它構造了硬件QAxObject。 然后,它構造提供參考的HardwareListener:QAxObject,QMutex和QWaitCondition。 然后,Worker的構造函數將HardwareListener對象移動到另一個線程並啟動它。 最后,HMI的構造函數啟動Worker的線程。

然后,當用戶單擊按鈕時,HMI將信號發送給工作程序。 Worker向硬件發送命令(該命令可能會阻塞線程幾秒鍾,這就是為什么我需要另一個線程中的HardwareListener不能錯過信號的原因)。 然后,Worker等待QWaitCondition(已鎖定QMutex之后)。

之后,硬件設備將信號發送到HardwareListener,從而喚醒QWaitCondition。 因此,Worker線程停止等待並完成其操作。 最后,工人通知HMI。

問題:

沒有創建/啟動Worker和HardwareListener線程。 一切都在主線程中完成,因此顯然不起作用。 我不會在線程之間交換任何特殊對象(因此不需要qRegisterMetaType()

題:

我的設計可以接受嗎? 可能還有其他方法可以完成,但在我看來這是最簡單的方法(考慮到復雜性)。


編輯:

我更改了代碼以刪除QThread繼承。 我改用moveToThread()方法。

現在,線程工作正常。 但是,我有一個ActiveX錯誤: QAxBase: Error calling IDispatch member NewProject: Unknown error

似乎與硬件的接口已損壞...知道嗎?

這是一些有趣的事情

You cannot move a QAxObject to another thread once it has been created.

解:

這就是我所發現的

從QThread繼承不是一個好的設計。 如果您正在做的工作是計算量大的事情,我建議您使用QThreadPool 我不比使用異步設計更好。 這意味着僅調用永不阻塞的函數,而是連接到通知您發生了事情的信號。

因此,例如,將命令發送到硬件並在硬件完成后發出信號。 如果硬件API不提供異步功能,則說明您不願意使用線程。 QtConcurrentRun可以幫助您。 通常,您不需要自己接觸線程。 沒有它,它的地獄要容易得多。

暫無
暫無

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

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