Reputation: 342
I'm writing an application in PyQt5 which will be used for calibration and test of a product. The important details:
\r\n
.During the test/calibration cycle the GUI needs to communicate with the devices, take readings, and log those readings to various boxes in the screen. The trouble is, with the slow UART communications (and the long time-outs if there is a comms drop-out) how do I keep the GUI responsive?
The Minimally Acceptable solution (already working) is to create a GUI which communicates over the serial port, but the user interface becomes decidedly sluggish and herky-jerky while the GUI is waiting for calls to serial.read()
to either complete or time out.
The Desired solution is a GUI which has a nice smooth responsive feel to it, even while it is transmitting and receiving serial data.
The Stretch Goal solution is a GUI which will log every single character of the serial communications to a text display used for debugging, while still providing some nice "message-level" abstraction for the actual logic of the application.
My present "minimally acceptable" implementation uses a state machine where I run a series of short functions, typically including the serial.write()
and serial.read()
commands, with pauses to allow the GUI to update. But the state machine makes the GUI logic somewhat tricky to follow; the code would be much easier to understand if the program flow for communicating to the device was written in a simple linear fashion.
I'm really hesitant to sprinkle a bunch of processEvents()
calls throughout the code. And even those don't help when waiting for serial.read()
. So the correct solution probably involves threading, signals, and slots, but I'm guessing that "threading" has the same two Golden Rules as "optimization": Rule 1: Don't do it. Rule 2 (experts only): Don't do it yet.
Are there any existing architectures or design patterns to use as a starting point for this type of application?
Upvotes: 0
Views: 883
Reputation: 244132
Qt is not only a library to make GUI but is a library that has other modules such as Qt Networt, Qt WebEngine, Qt Mqtt, etc. that work without blocking the Qt event loop, in its case it is best to use Qt SerialPort
avoiding the problem that always brings threads. For example, in this answer I show the implementation of the same solution using Qt SerialPort and threads + pyserial.
Upvotes: 1
Reputation: 342
Okay for the past few days I've been digging, and figured out how to do this. Since there haven't been any responses, and I do think this question could apply to others, I'll go ahead and post my solution. Briefly:
getdata()
operation in the middle of a function. Instead, the worker thread had to be constructed as a bunch of individual functions, each one of which gets kicked off after it receives the appropriate Signal from the GUI.All in all it ended up being a pretty straightforward application of existing principles, but I'm writing it down so hopefully the next guy doesn't have to go down so many blind alleys like I did along the way.
Upvotes: 0