在PyQt4中使用PyQtGraph进行实时绘图

时间:2017-01-16 14:51:29

标签: python pyqt pyqt4 pyqtgraph

我是Python和TRYING的新手来制作PyQt4应用程序,我在其中嵌入了PyQtGraph。我有这个奇妙的PyQtGraph现场绘图仪:

from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import random

app = QtGui.QApplication([])
p = pg.plot()
curve = p.plot()
data = [0]

def updater():

    data.append(random.random())
    curve.setData(data) #xdata is not necessary


timer = QtCore.QTimer()
timer.timeout.connect(updater)
timer.start(0)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

为了嵌入更大的PyQt4应用程序,我需要一个包含pyqtgraph.PlotWidget()的布局。为此,我在MainWindow中设置了一个centralWidget。我创建了一个按钮,它应该像前面的代码一样开始绘图,但是当我通过绘图仪函数调用updater函数时没有任何反应:

import sys
from PyQt4 import QtCore, QtGui
import pyqtgraph as pg
import random

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.central_widget = QtGui.QStackedWidget()
        self.setCentralWidget(self.central_widget)
        login_widget = LoginWidget(self)#to say where the button is
        login_widget.button.clicked.connect(self.plotter)
        self.central_widget.addWidget(login_widget)

    def plotter(self):
        self.data =[0]
        timer = QtCore.QTimer()
        timer.timeout.connect(self.updater)
        timer.start(0)

    def updater(self):

        self.data.append(random.random())
        plot.setData(self.data)

class LoginWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        global plot
        super(LoginWidget, self).__init__(parent)
        layout = QtGui.QHBoxLayout()
        self.button = QtGui.QPushButton('Start Plotting')
        layout.addWidget(self.button)
        plot = pg.PlotWidget()
        layout.addWidget(plot)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QtGui.QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

什么都没发生,因为我必须线程?

2 个答案:

答案 0 :(得分:3)

代码中有几点需要考虑 首先,与@ luddek的回答方向相同,你需要跟踪你的变量。如果在类方法中定义变量并且此类方法已完成执行,则该变量将丢失。从外面看不到它。
因此,使用实例变量是一个好主意 self.plot代替plot
self.timer代替timer
self.login_widget代替login_widget
(另外,我不建议在PyQt程序中使用global,尽管它是有效的代码)

接下来,PlotWidget没有setData方法。将数据绘制到PlotItem的图中更为复杂:
pg.PlotWidget()有一个PlotItem,您可以通过.getPlotItem()获得。然后你需要在其上调用plot(),它返回你想要添加数据的实际曲线。在下面的示例中,我介绍了新变量self.curve,您可以通过self.curve.setData(self.data)

向其添加数据

这是完整的工作代码。

from PyQt4 import QtCore, QtGui
import pyqtgraph as pg
import random

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.central_widget = QtGui.QStackedWidget()
        self.setCentralWidget(self.central_widget)
        self.login_widget = LoginWidget(self)
        self.login_widget.button.clicked.connect(self.plotter)
        self.central_widget.addWidget(self.login_widget)

    def plotter(self):
        self.data =[0]
        self.curve = self.login_widget.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)

class LoginWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(LoginWidget, self).__init__(parent)
        layout = QtGui.QHBoxLayout()
        self.button = QtGui.QPushButton('Start Plotting')
        layout.addWidget(self.button)
        self.plot = pg.PlotWidget()
        layout.addWidget(self.plot)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QtGui.QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

答案 1 :(得分:2)

updater()未被调用,因为垃圾收集器删除了计时器。

您需要在计时器的某处保留一个引用。例如,您可以在__init__

中创建引用
def __init__(self, parent=None):
    ...
    self.timer = QtCore.QTimer()