我在不同的DLL项目中包装libcommuni,它使用Qt,它不使用Qt。据我所知,我需要运行Qt消息泵(通过QCoreApplication
)以确保网络,信号等正常工作。但是,我正在遇到一些问题,想弄清楚如何做到这一点。
基本上,我想在DLL中启动一个线程,它调用QCoreApplication::exec()
并泵送所有Qt事件。然后我想编组对Qt主线程的不同线程的DLL的外部调用,所以我可以安全地使用libcommuni。
看起来推荐的方法是使用信号和插槽,但我一直无法使用它。我在QObject
类上创建一个通过DLL调用的信号,并将其连接到运行Qt消息泵的QThread
上的插槽。但是,如果在连接信号和插槽时指定Qt::QueuedConnection
,则在发出信号时永远不会传递消息。如果我完全省略Qt::QueuedConnection
,则在调用线程而不是Qt主线程上立即调用该槽。
我还尝试在DLL线程上显式调用QCoreApplication::postEvent()
来向Qt主线程发送事件,但永远不会在目标event(QEvent)
中调用QThread
。
关于我在这里做错了什么的想法?我猜我不太了解Qt的线程模型。
答案 0 :(得分:1)
当您使用QObject::connect
而未指定连接类型时 - 它使用Qt::AutoConnection
,如果信号和广告位在单个线程中,则变为Qt::DirectConnection
,或Qt::QueuedConnection
,如果他们在不同的线程。因此,在您的情况下,我可以说,目前,当您将信号与插槽连接时,它们所属的对象位于一个线程中。
为了使Qt::QueuedConnection
有效,你需要一个包含插槽的线程中的事件循环。
使用QThread有两种主要方式:
您可以派生QThread
并重写QThread::run
。在这种情况下,你应该做几件事:
moveToThread(this)
。run
方法调用exec中;致电exec
后,主题将立即离开QThread::quit
。您可以在调用{之前'派生QObject
,创建QThread
对象,并在您的对象上调用QThread::moveToThread
(顺便说一下,应该创建它而不指定父对象) {1}}。
在你的情况下,我建议使用第二种方法。
这是关于线程的,但我不太确定,您的问题与QThread::start
无关。