python - 串行端口块 GUI - 发射信号块 PyQt-App
问题描述
我有一个 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 的阻塞?我可以发送一些指示信号已被处理的返回值吗?
解决方案
问题是由发射信号和插槽之间的连接类型引起的。
以前我用过:
.connect(self._move_thread.motor_move)
当发出信号 PyQt5 确定应该建立什么类型的连接。在这种情况下,总是决定选择Qt.DirectConnection
立即运行插槽但等待(!)直到插槽返回的 a。这显示在输出中:
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 中排队,信令线程不等待槽返回。现在的输出是:
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
推荐阅读
- swift - Swift中的SQLite绑定未知数据类型
- angularjs-directive - Angular Js Ng-Click中的JQuery数据表不起作用?
- javascript - Kendo Grid - 在按钮单击中传递编辑的值
- angularjs - AngularJS函数到另一个文件
- c# - 如何使用 ToUnicode 条目获取 RDLC 报告呈现 PDF,以便从生成的 PDF 中复制粘贴非 ansi 文本
- emacs - emacsclient,在终端中禁用美化符号模式?
- ios - 是否有与 Android API 方法 getAllCellInfo 等效的 iOS?
- vba - 禁用“关闭时保存”提示时 Excel 拒绝关闭
- elasticsearch - Elasticsearch 不区分大小写的嵌套查询字符串
- c++ - 为什么 SFML 位置是浮动的?