简体   繁体   中英

QThread doesn't start

Sorry for the length of this post. But I am stuck for two days now....

I am working on a Qt 4.6 Windows application that communicates with a hardware device through ActiveX.

When I send a command, the device does some stuff and when it's done (can take up to one minute) it emits a signal. I need to wait this signal to know if everything went okay (or not) and do some actions in consequence.

A command is sent to the device when a user clicks a button. And obviously, I don't want the HMI to freeze.

I am convinced I have to use threads. So I identified three threads:

  1. the main thread corresponding to the HMI
  2. the hardware controller (which locks after a command is sent and waits a signal)
  3. a hardware notification listener that continuously gets signals from the hardware and unlock the thread 2

Here is the class diagram:

类图]

And a sequence diagram to show how I see things:

顺序图

Explanations:

When the user launches my application, the HMI is created. The constructor of the HMI calls the constructor of the Worker. It constructs the hardware QAxObject. Then it constructs the HardwareListener giving in reference: the QAxObject, the QMutex and the QWaitCondition. Then the constructor of the Worker moves the HardwareListener object to another thread and starts it. Finally, the constructor of the HMI starts the thread of the Worker.

Then, when the user clicks a button, the HMI sends a signal to the Worker. The Worker sends a command to the hardware (that command may block the thread several seconds that's why I need the HardwareListener in another thread not to miss a signal). Then the Worker waits for a QWaitCondition (after having locked the QMutex).

After that, the hardware device sends a signal to the HardwareListener which wakes up the QWaitCondition. Therefore, the Worker thread stops waiting and finishes its actions. Finally, the Worker informs the HMI.

Problem:

The Worker and HardwareListener threads aren't created/started. Everything is done in the main thread so, obviously, it doesn't work. I don't exchange any special object between threads (so no need for qRegisterMetaType() )

Question:

Is my design acceptable? There may be some other ways to do but it seems to me this is the most straightforward (taking into account the complexity).


EDIT:

I've changed my code to remove the QThread inheritance. I use the moveToThread() method instead.

Now the threads work fine. HOWEVER I have an ActiveX error: QAxBase: Error calling IDispatch member NewProject: Unknown error .

It seems the interfacing with the hardware is broken... Any idea?

Here is something interesting :

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

SOLUTION:

Here is what I have found .

Inheriting from QThread is not good design. If the work you are doing is computational heavy I would recommend using QThreadPool . I not than its better to use an asynchronous design. This means only calling function which never block and instead connect to signals notifying you that something happened.

So for example sending the command to the hardware and emitting a signal once the hardware is done. If the hardware API doesn't supply async functions than you are stuck with using threads. QtConcurrentRun can help with that. Usually you should not need to touch threads yourself; and its a hell of a lot easier without.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM