串行端口块 GUI - 发射信号块 PyQt-App

serial port blocks GUI - emitting signal blocks PyQt-App

我有一个 PyQt5 应用程序,其中一个按钮触发与串行设备的通信。虽然应用程序是 运行,但它还会从相机中抓取图像。但是,当串行通信忙于 reading/writing 时,GUI 不会更新,也不会显示来自相机的图像。

我试图通过 3 个单独的线程来解决问题 - 1:GUI,2:串行通信,3:图像抓取。它们之间的通信是通过信号完成的。不幸的是,当我向第二个线程发出信号进行通信时,第一个线程 (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 的信号做出反应并绘制新图像。线程 2 的信号似乎会阻塞,直到串行通信线程中的所有内容都完成。

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? 我可以发送一些 return 值来指示信号已被处理吗?

问题是由发射信号和插槽之间的连接类型引起的。

之前我用过:

.connect(self._move_thread.motor_move)

当发出信号时,PyQt5 确定应该建立哪种类型的连接。在这种情况下,总是决定使用 Qt.DirectConnection,它会立即运行插槽,但会等待 (!) 直到插槽 returns。这显示在输出中:

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)

插槽的处理在 EventLoop 中排队,信号线程不等待插槽 return。现在的输出是:

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