QThread没有启动

时间:2013-04-09 14:40:15

标签: c++ qt qthread qaxobject

对不起这篇文章的篇幅。但我现在被困了两天......

我正在开发一个Qt 4.6 Windows应用程序,它通过ActiveX与硬件设备进行通信。

当我发送命令时,设备会执行一些操作,当它完成时(最多可能需要一分钟),它会发出一个信号。我需要等待这个信号才能知道一切是否正常(或不是)并做了一些后果。

当用户单击按钮时,会向设备发送命令。显然,我不希望HMI冻结。

我确信我必须使用线程。所以我确定了三个主题:

  1. 与HMI对应的主线程
  2. 硬件控制器(在发送命令后锁定并等待信号)
  3. 硬件通知侦听器,持续从硬件获取信号并解锁线程2
  4. 这是类图:

    class diagram]

    以及显示我如何看待事物的序列图:

    sequence diagram

    说明:

    当用户启动我的应用程序时,将创建HMI。 HMI的构造函数调用Worker的构造函数。它构造硬件QAxObject。然后它构造了HardwareListener,提供了引用:QAxObject,QMutex和QWaitCondition。然后,Worker的构造函数将HardwareListener对象移动到另一个线程并启动它。最后,HMI的构造函数启动Worker的线程。

    然后,当用户单击按钮时,HMI会向Worker发送信号。 Worker向硬件发送命令(该命令可能会阻塞线程几秒钟,这就是为什么我需要另一个线程中的HardwareListener不要错过信号的原因)。然后工人等待QWaitCondition(在锁定QMutex之后)。

    之后,硬件设备向HardwareListener发送信号,该信号唤醒QWaitCondition。因此,Worker线程停止等待并完成其操作。最后,工人通知HMI。

    问题:

    未创建/启动Worker和HardwareListener线程。一切都在主线程中完成,显然,它不起作用。我不在线程之间交换任何特殊对象(因此不需要qRegisterMetaType()

    问题:

    我的设计是否可以接受?可能还有其他一些方法可以做,但在我看来,这是最直接的(考虑到复杂性)。


    编辑:

    我已更改代码以删除QThread继承。我改为使用moveToThread()方法。

    现在线程运行正常。 HOWEVER 我有一个ActiveX错误:QAxBase: Error calling IDispatch member NewProject: Unknown error

    似乎与硬件的接口被破坏了......任何想法?

    Here is something interesting

    You cannot move a QAxObject to another thread once it has been created.
    

    SOLUTION:

    Here is what I have found

1 个答案:

答案 0 :(得分:0)

Inheriting from QThread is not good design.如果你正在做的工作计算量很大,我建议使用QThreadPool。我不是更好地使用异步设计。这意味着只调用从不阻塞的函数,而是连接到通知您发生了某些事情的信号。

因此,例如,一旦硬件完成,将命令发送到硬件并发出信号。如果硬件API不提供异步功能而不是使用线程。 QtConcurrentRun可以帮助解决这个问题。通常你不需要自己触摸线程;如果没有它就会变得更容易。