[英]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的主要方法有兩種:
您可以派生QThread
並重寫QThread::run
。 在這種情況下,您應該做幾件事:
moveToThread(this)
。 run
方法中調用exec; 調用QThread::quit
之后,線程將立即退出exec
。 你可以得到你QObject
,創建QThread
對象,並調用QThread::moveToThread
之前調用你的對象(其中,順便說一下,應該沒有指定父創建)上QThread::start
。
在您的情況下,我建議您使用第二種方法。
那是關於線程的,但是我不太確定,您的問題與QCoreApplication::exec
沒有關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.