【发布时间】:2019-02-07 19:32:43
【问题描述】:
我在 PyQt 的帮助下在 python3 中开发了一个 SCADA。我希望我的程序能够连续指示通过 RS-485 接口接收到的各种参数,但是,在开始后的几分钟内(总是不同的时间),GUI 停止自我更新。同时,GUI 保持响应,如果我单击其中一个动画 QAbstractButtons,GUI 会在短时间内再次按预期工作。 Linux 和 Windows 都会出现此问题。
该程序有几个工作线程:一个用于RS-485交换,一个用于读取/写入各种数据到磁盘,一个用于解码接收到的数据包并刷新内存中的数据,一个用于请求队列管理等。它们都工作在while (True): time.sleep(...) 的循环 - 完成这项工作。 GUI 在主线程中实现。
数据用 QLabels 表示。 QLabel.setText 被添加到包含 QLabels 的 QWidgets 的painterEvent() 中。
当 GUI 停止更新时,其他线程启动并运行:交换正在运行,请求队列正在形成等。尽管没有更新,但 GUI 保持响应并对 QAbstractButton 的点击做出反应。
我尝试将 gui.update() 或 app.processEvents() 添加到其中一个工作线程中,尝试通过主线程中的 QTimer 强制更新。结果是一样的:它工作了一会儿,然后就停止了。
我尝试增加刷新线程的 time.sleep 并在更长的时间间隔(0.5 到 5 秒)内强制更新主小部件,这似乎对这种情况有很大帮助,这样它可以运行几分钟,但它仍然没有解决问题。
我很想展示代码,但是整个代码太庞大了,无法在此处发布,如果我可以将其缩小到至少一百行,我现在已经解决了这个问题。因此,如果你们中的任何人至少可以分享一些关于寻找什么的一般性考虑,我会非常高兴。
更新: 这似乎有效,我明天让它运行几个小时来确认:
update_timer = QTimer()
update_timer.setSingleShot(False)
update_timer.timeout.connect(self.gui.repaint)
update_timer.setInterval(500)
update_timer.start()
我假设 self.gui.update() 不起作用,因为 dataChanged() 可能没有发出并且控制传递而不是 repaint()。据我了解,上述解决方案不是更新小部件的正确方法。
所以,问题实际上归结为以下几点:
更新主 QWidget 的正确方法是什么?如何让程序知道它需要重绘,可能使用 dataChanged() 信号?
【问题讨论】:
-
很多文字,没有代码。你为什么不让它相反,这样更容易帮助你? How to create a Minimal, Complete, and Verifiable example
标签: python-3.x pyqt5