簡體   English   中英

調用Qt主線程

[英]Marshal calls to Qt main thread

我將使用Qt的libcommuni包裝在另一個不使用Qt的DLL項目中。 據我所知,我需要運行Qt消息泵(通過QCoreApplication )以確保網絡,信號等正常工作。 但是,我遇到了一些問題,想方設法做到這一點。

基本上,我想在DLL中啟動一個線程,該線程調用QCoreApplication::exec()並泵送所有Qt事件。 然后,我想將對在另一個線程上的DLL的外部調用封送給Qt主線程,以便可以安全地使用libcommuni。

似乎推薦的方法是為此使用信號和插槽,但是我一直無法使其正常工作。 我在通過DLL調用的QObject類上創建一個信號,並將其連接到運行Qt消息泵的QThread上的插槽。 但是,如果在連接信號和插槽時指定Qt::QueuedConnection ,則在發出信號時永遠不會傳遞消息。 如果我完全省略Qt::QueuedConnection ,則立即在調用線程而不是Qt主線程上調用該插槽。

我也嘗試過在DLL線程上顯式調用QCoreApplication::postEvent()以將事件發送到Qt主線程,但是event(QEvent)從未在目標QThread

對我在這里做錯的任何想法嗎? 我猜我不太了解Qt的線程模型。

當您使用QObject::connect不指定連接類型-它使用Qt::AutoConnection ,這變成Qt::DirectConnection如果信號和槽是在單個線程中,或進入Qt::QueuedConnection ,如果它們是在不同的線程。 因此,就您的情況而言,我可以說,目前,當您將信號與插槽連接時,它們所屬的對象位於一個線程中。

為了使Qt::QueuedConnection正常工作,您需要在包含插槽的線程中進行事件循環。

使用QThread的主要方法有兩種:

  1. 您可以派生QThread並重寫QThread::run 在這種情況下,您應該做幾件事:

    • 創建線程的對象時,不要指定父對象; 手動刪除該對象。
    • 在線程的構造函數中,調用moveToThread(this)
    • 在所有初始化之后但在所有刪除之前,在線程的run方法中調用exec; 調用QThread::quit之后,線程將立即退出exec
  2. 你可以得到你QObject ,創建QThread對象,並調用QThread::moveToThread之前調用你的對象(其中,順便說一下,應該沒有指定父創建)上QThread::start

在您的情況下,我建議您使用第二種方法。

那是關於線程的,但是我不太確定,您的問題與QCoreApplication::exec沒有關系。

暫無
暫無

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

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