Обновление n PlotWidgets в PyQt4 для построения графиков в реальном времени

Я ПЫТАЮСЬ создать приложение, в котором я хочу иметь несколько PlotWidgets, отображающих сигнал от 5 датчиков, которые у меня есть в моем Arduino. Как только у меня есть два обновляющихся графика, графический интерфейс не отвечает, и мне нужно приостановить/перезапустить график и всплывающие предупреждения для некоторых значений. Чтобы решить эту проблему, я начал исследования, чтобы использовать 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, но сначала мне нужно знать, возможно ли это, или я трачу свои дни и сон впустую. У кого-нибудь есть намек на то, как я могу заставить его работать?


person Ivy    schedule 19.01.2017    source источник


Ответы (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 по последовательному каналу в другом потоке (графический интерфейс не будет блокироваться), но вам нужно будет отправить данные через сигнал PyQt в основной поток и запустите там команду построения графика. В StackOverflow есть много примеров того, как правильно работать с PyQt (например, здесь)

person three_pineapples    schedule 20.01.2017
comment
Спасибо за примеры @three_pinaples - person Ivy; 20.01.2017