C++ 封送对Qt主线程的调用
我将使用Qt的libcommuni包装到另一个不使用Qt的DLL项目中。据我所知,我需要运行Qt消息泵(通过C++ 封送对Qt主线程的调用,c++,qt,events,C++,Qt,Events,我将使用Qt的libcommuni包装到另一个不使用Qt的DLL项目中。据我所知,我需要运行Qt消息泵(通过QCoreApplication)以确保网络、信号等正常工作。然而,我遇到了一些问题,想知道如何做到这一点 基本上,我想在DLL中启动一个线程,它调用QCoreApplication::exec()并泵送所有Qt事件。然后,我想将对DLL的外部调用(位于不同线程上)封送到Qt主线程,这样我就可以安全地使用libcommuni 看起来推荐的方法是使用信号和插槽,但我一直无法让它工作。我在通过
QCoreApplication
)以确保网络、信号等正常工作。然而,我遇到了一些问题,想知道如何做到这一点
基本上,我想在DLL中启动一个线程,它调用QCoreApplication::exec()
并泵送所有Qt事件。然后,我想将对DLL的外部调用(位于不同线程上)封送到Qt主线程,这样我就可以安全地使用libcommuni
看起来推荐的方法是使用信号和插槽,但我一直无法让它工作。我在通过DLL调用的QObject
类上创建了一个信号,并将其连接到运行Qt消息泵的QThread
上的一个插槽。但是,如果在连接信号和插槽时指定Qt::QueuedConnection
,则在发出信号时永远不会传递消息。如果我完全省略了Qt::QueuedConnection
,那么将立即在调用线程而不是Qt主线程上调用插槽
我还尝试在DLL线程上显式调用QCoreApplication::postEvent()
,将事件发送到Qt主线程,但在目标QThread
中从未调用event(QEvent)
你知道我做错了什么吗?我猜我不太理解Qt的线程模型。当您使用
QObject::connect
而不指定连接类型时,它使用Qt::AutoConnect
,如果信号和插槽在单个线程中,它会变成Qt::DirectConnection
,或者变成Qt::QueuedConnection
,如果它们在不同的线程中。所以,在你的例子中,我可以说,目前,当你把信号和插槽连接起来时,它们所属的对象都位于一个线程中
为了使Qt::QueuedConnection
工作,您需要在包含插槽的线程中创建一个事件循环
使用QThread的主要方法有两种:
QThread
并重写QThread::run
。在这种情况下,您应该做几件事:
- 创建线程对象时,不要指定父对象;手动删除此对象
- 在线程的构造函数中调用
moveToThread(this)
- 在线程的
方法中,在所有初始化之后,但在所有删除之前调用exec;调用run
后,线程将立即离开QThread::quit
exec
QThread::start
之前,您可以派生QObject
,创建QThread
对象,并在对象上调用QThread::moveToThread
(顺便说一句,应该在不指定父对象的情况下创建该对象)QCoreApplication::exec
无关