串行端口块 GUI - 发射信号块 PyQt-App
Posted
技术标签:
【中文标题】串行端口块 GUI - 发射信号块 PyQt-App【英文标题】:serial port blocks GUI - emitting signal blocks PyQt-App 【发布时间】:2021-04-29 09:47:01 【问题描述】:我有一个 PyQt5 应用程序,其中一个按钮触发与串行设备的通信。在应用程序运行时,它还会从相机中获取图像。但是,当串行通信忙于读/写时,GUI 不会更新,也不会显示来自相机的图像。
我试图通过 3 个单独的线程来解决这个问题 - 1:GUI,2:串行通信,3:图像抓取。它们之间的通信由 Signals 完成。不幸的是,当我通知第二个线程进行通信时,第一个线程(GUI)没有更新。
布局基本上是这样的:
Thread1 = GUI:
signal to Thread2, when serial comm requested
slot for Thread3, for image data grabbed from device
Thread2 = Serial comm:
slot for Thread1, for data to be send via serial port
Thread3 = Image grab:
signal to Thread1, when new image data is available
所以,当我需要通过串口发送一些东西时,Thread1 会向 Thread2 发出一个信号,然后应该继续执行它的消息循环,例如对来自 Thread3 的信号做出反应并绘制新图像。到 Thread2 的信号似乎被阻塞了,直到一切都在串行通信线程中完成。
Thread2 中的槽是这样的:
@pyqtSlot(int, int, int)
def motor_move(self, motor, direction, steps):
"""
Move motor one step in given direction.
Parameters
----------
motor : int
Motor index.
direction : int
Direction.
Returns
-------
None.
"""
if self._motor.serial_port:
self._motor.motor_move(motor, steps, direction) # here the serial communication happens
现在问题: 串口忙时如何解除对 GUI 的阻塞? 我可以发送一些表明信号已被处理的返回值吗?
【问题讨论】:
【参考方案1】:问题是由发射信号和插槽之间的连接类型引起的。
我以前用过:
.connect(self._move_thread.motor_move)
当发出信号 PyQt5 确定应该建立什么类型的连接。在这种情况下,总是决定使用Qt.DirectConnection
,它会立即运行插槽,但会等待(!)直到插槽返回。这显示在输出中:
Arduino got: " " # what I have sent
0.0 5.0 # slot takes 5 seconds to return
Done # this is the signaling thread continuing after the slot returns
使用:
.connect(self._move_thread.motor_move, , type=Qt.QueuedConnection)
slot 的处理在 EventLoop 中排队,并且信令线程不等待 slot 返回。现在的输出是:
Arduino got: " " # what I have sent
Done # this is the signaling thread continuing immediately after emitting the signal
0.0 5.0 # slot takes 5 seconds to return
【讨论】:
为什么不使用 QSerialPort 从而避免线程问题? ***.com/questions/55070483/… 不知道这些。但它们无法解决我的串行设备响应速度慢的问题,因此在没有放入单独的线程时会阻塞我的应用程序。 您的设备可以慢也可以快,但 QSerialPort 的优势在于它使用信号来获取数据,避免了增加不必要的复杂性。与 pyserial 不同,如果有数据则等待,而不是 QSerialPort 连接一个函数,该函数将在几乎没有任何数据时调用。 我试过 QSerialPort。 GUI 仍然会冻结一小会儿,但总体而言集成效果更好。我可以接受现在的方式。感谢您的建议。以上是关于串行端口块 GUI - 发射信号块 PyQt-App的主要内容,如果未能解决你的问题,请参考以下文章