很抱歉这篇文章太长了。但我现在被困了两天..。
我正在开发一个QT4.6Windows应用程序,它通过ActiveX与硬件设备通信。
当我发送命令时,设备会做一些事情,当它完成时(可能需要一分钟)它就会发出一个信号。我需要等待这个信号,以了解是否一切顺利(或不顺利),并采取一些行动的结果。
当用户单击按钮时,会向设备发送命令。很明显,我不想让人机界面冻结。
我相信我必须使用线程。所以我确定了三个线程:
下面是类图:

以及一个序列图来展示我是如何看待事物的:

Explanations:
当用户启动我的应用程序时,就会创建HMI。HMI的构造函数调用工作人员的构造函数。它构造了硬件QAxObject。然后构造引用中的HardwareListener : QAxObject、QMutex和QWaitCondition。然后,工作人员的构造函数将HardwareListener对象移动到另一个线程并启动它。最后,HMI的构造函数启动工作线程。
然后,当用户单击一个按钮时,人机界面会向工人发送一个信号。工作人员向硬件发送一个命令(该命令可能会阻塞线程几秒钟,这就是为什么我需要在另一个线程中的HardwareListener不丢失一个信号)。然后工作人员等待一个QWaitCondition (在锁定了QMutex之后)。
然后,硬件设备向唤醒HardwareListener的QWaitCondition发送信号。因此,工作线程停止等待并完成其操作。最后,工人通知人机界面。
问题:
未创建/启动工作线程和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.解决方案:
发布于 2013-04-09 15:16:00
继承QThread并不是一个好的设计。,如果您所做的工作计算量很大,我建议使用QThreadPool。我并不比使用异步设计更好。这意味着只调用函数,该函数从不阻塞,而是连接到通知您发生了什么事情的信号。
例如,向硬件发送命令,并在硬件完成后发出信号。如果硬件API没有提供异步函数,则需要使用线程。QtConcurrentRun可以帮上忙。通常,你不需要自己去触摸线程,如果没有线程的话,这会容易得多。
https://stackoverflow.com/questions/15904958
复制相似问题