在 PyQt4 中更新 n 个 PlotWidgets 以进行实时绘图
Posted
技术标签:
【中文标题】在 PyQt4 中更新 n 个 PlotWidgets 以进行实时绘图【英文标题】:Updating n PlotWidgets in PyQt4 for Live Plotting 【发布时间】:2017-06-04 10:26:11 【问题描述】:我正在尝试制作一个应用程序,我希望有几个 PlotWidgets 可以绘制来自我的 Arduino 中多达 5 个传感器的信号。一旦我有两个更新的绘图,GUI 就没有响应,我需要暂停/重新启动绘图,并弹出一些值的警报。为了解决这个问题,我已经开始研究以使用 QThread,但这对于 PyQtGraph 可能是不可能的,因为我们不能在多个线程中完成绘图?我的两个 PlotWidgets 代码如下所示:
from PyQt4 import QtCore, QtGui
import pyqtgraph as pg
import random
import sys
class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
layout = QtGui.QHBoxLayout()
self.button = QtGui.QPushButton('Start Plotting Left')
layout.addWidget(self.button)
self.button.clicked.connect(self.plotter)
self.button2 = QtGui.QPushButton('Start Plotting Right')
layout.addWidget(self.button2)
self.button2.clicked.connect(self.plotter2)
self.plot = pg.PlotWidget()
layout.addWidget(self.plot)
self.plot2 = pg.PlotWidget()
layout.addWidget(self.plot2)
self.setLayout(layout)
def plotter(self):
self.data =[0]
self.curve = self.plot.getPlotItem().plot()
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updater)
self.timer.start(0)
def updater(self):
self.data.append(self.data[-1]+0.2*(0.5-random.random()) )
self.curve.setData(self.data)#Downsampling does not help
def plotter2(self):
self.data2 =[0]
self.curve2 = self.plot2.getPlotItem().plot()
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updater2)
self.timer.start(0)
def updater2(self):
self.data2.append(self.data[-1]+0.2*(0.5-random.random()) )
self.curve2.setData(self.data) #Downsampling does not help
if __name__ == '__main__':
app = QtGui.QApplication([])
window = MainWindow()
window.show()
app.exec_()
我已经准备好从 QThread 阅读和尝试很多东西,但首先我需要知道这是否可能,或者我是否在浪费时间和睡眠。有没有人暗示我怎样才能让它工作?
【问题讨论】:
【参考方案1】:您的代码有几个印刷错误使其无法正常工作
在updater2
中,您使用的是self.data
而不是self.data2
。代码应该是:
def updater2(self):
self.data2.append(self.data2[-1]+0.2*(0.5-random.random()) )
self.curve2.setData(self.data2) #Downsampling does not help
另外,在创建第二个计时器时,将它存储在与第一个计时器相同的变量中,这会导致它停止。更正后的代码应为:
def plotter2(self):
self.data2 =[0]
self.curve2 = self.plot2.getPlotItem().plot()
self.timer2 = QtCore.QTimer()
self.timer2.timeout.connect(self.updater2)
self.timer2.start(0)
请注意,在计时器已经启动后“启动”它(也就是单击同一个按钮两次)会导致程序崩溃。您可能应该禁用按钮,或者再次单击停止计时器或其他东西。这取决于你。
关于线程,您可能会通过在另一个线程中通过串行读取 arduino 中的数据来从线程中获得一些性能提升(GUI 不会锁定),但您需要通过 PyQt 发送数据向主线程发出信号并在那里运行绘图命令。 ***上有很多关于如何正确使用PyQt线程的例子(例如here)
【讨论】:
感谢@three_pinaples 的示例以上是关于在 PyQt4 中更新 n 个 PlotWidgets 以进行实时绘图的主要内容,如果未能解决你的问题,请参考以下文章
从命令提示符更新 Python 版本并将 PyQt4 转换为 PyQt5
如何以编程方式更改/更新 Python PyQt4 TableView 中的数据?