2017-01-23 7 views
1

며칠 전 here 며칠 전 해결 된 질문이 계속됨에 따라 두 개의 PyQtGraph의 PlotWidgets가 임베드 된 PyQt4 GUI가 생겼습니다. 각 PygtGraph의 PlotWidgets는 스레드가 임의로 추가하는 배열의 데이터를 각각 설정/업데이트합니다. 단추. 그것은 아름답게 작동하고, GUI는 반응 적입니다. 그러나 그래프가 각 PlotWidgets 내부에서 업데이트를 보여주는 것을 멈추고 PlotWidgets 내부에 그려진 업데이트를 최소화/최대화해야한다는 요지가 있습니다. 코드는 외모와 같은 :QQreading PyQt4의 PyQtGraph PlotWidgets

import random 
import sys 

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


class MyThread(QtCore.QThread): 
    def __init__(self, curve, parent=None): 
     super(MyThread, self).__init__(parent=parent) 
     self.curve = curve 
     self.data = [0] 
     app.processEvents()#increases the time the drawings are shown 

    def run(self): 
     app.processEvents() #increases the time the drawings are shown 
     while True: 
      self.data.append(self.data[-1] + 0.2 * (0.5 - random.random())) 
      self.curve.setData(self.data, downsample=10) #crashes without 
      time.sleep(0.1) 


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) 
     self.button.clicked.connect(self.plotter) 
     app.processEvents() 

    def plotter(self): 
     self.curve = self.plot.getPlotItem().plot() 
     myThread = MyThread(self.curve, self) 
     myThread.start() 


class MainWindow(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     self.centralwidget = QtGui.QWidget(self) 
     self.setCentralWidget(self.centralwidget) 
     self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) 
     self.login_widget_1 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_1) 
     self.login_widget_2 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_2) 
     self.setCentralWidget(self.centralwidget) 


if __name__ == '__main__': 
    global app 
    app = QtGui.QApplication(sys.argv) 
    w = MainWindow() 
    w.show()  
    sys.exit(app.exec_()) 

나는 GUI에서 업데이트가 나를 매우 기쁘게합니다 얻을하기 위해/최대화 최소화하지 않아도을 위해 무엇을 할 수 있는지에 대한 어떤 단서 또는 해결.

아래의 대답 @ImportanceOfBeingErnest의 조언에 따라, 나는 GUI와 같은 신호 및 슬롯 스레드 연결하는 Python Wiki을 다음 시도 :

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


class MyThread(QtCore.QThread): 
    def __init__(self, parent=None): 
     super(MyThread, self).__init__(parent=parent) 
     self.data = [0] 

    def run(self): 
     while True: 
      self.data.append(self.data[-1] + 0.2 * (0.5 - random.random())) 
      self.emit(SIGNAL("output(data)"), self.data) 
      time.sleep(0.1) 


class LoginWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(LoginWidget, self).__init__(parent) 
     self.myThread = MyThread() 
     layout = QtGui.QHBoxLayout() 
     self.button = QtGui.QPushButton('Start Plotting') 
     layout.addWidget(self.button) 
     self.plot = pg.PlotWidget() 
     layout.addWidget(self.plot) 
     self.setLayout(layout) 
     self.button.clicked.connect(self.plotter) 
     self.connect(self.myThread, SIGNAL("output(data)"), self.plotter) 

    def plotter(self, data): 
     self.curve = self.plot.getPlotItem().plot() 
     self.curve.setData(data, downsample=10) 


class MainWindow(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     self.centralwidget = QtGui.QWidget(self) 
     self.setCentralWidget(self.centralwidget) 
     self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) 
     self.login_widget_1 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_1) 
     self.login_widget_2 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_2) 
     self.setCentralWidget(self.centralwidget) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    w = MainWindow() 
    w.show() 
    sys.exit(app.exec_()) 

을하지만 그것은 나에게 오류 제공 :

:
"in self.connect(self.myThread, SIGNAL("output(data)"), self.plotter) 
NameError: name 'SIGNAL' is not defined" 

question from 4 years ago를 읽고, 나는 다음과 같은 오류를 얻을 수 QtCore.SIGNAL에 의해 신호를 대체

다음과 같이 형식 오류를 ingnoring의 : 내가

"in plotter 
self.curve.setData(data, downsample=10) 
File "C:\Users\iyv\AppData\Local\Programs\Python\Python34_64\lib\site- 
packages\pyqtgraph\graphicsItems\PlotDataItem.py", line 381, in setData 
raise Exception('Invalid data type %s' % type(data)) 
Exception: Invalid data type <class 'bool'>" 

:

try: 
    self.connect(self.myThread, QtCore.SIGNAL("output(data)"), self.plotter) 
except TypeError: 
    pass 

GUI는 시작하지만, 나는 마침내 나는 다음과 같은 오류를 얻을 self.plotter 기능 버튼을 클릭하고 연결할 때 꽤 혼란스러워. PyQtGraph에 문의해야합니까? 도움을 주신 모든 분들께 감사드립니다.

+0

나는 아래의 나의 대답을 편집하여 실습 예제를 보여 주었다. – ImportanceOfBeingErnest

답변

2

GUI와 스레드를 별도로 유지해야합니다. 이 경우 플롯 위젯과 같은 GUI 객체를 공유해서는 안됩니다!

데이터가 그리 크지 않고 초당 10 회만 업데이트되므로 스레딩이 필요한지 잘 모르겠습니다. 그러나 사용하기로 결정했다면 스레드와 GUI 사이에서 통신하려면 signals and slots 만 사용하십시오.


다음은 스레딩을 사용하고 잘 작동하는 프로그램의 수정 된 버전입니다. 새 스타일 signals and slots을 사용합니다. 이것은 단지 object을 데이터 유형으로 사용할 수 있기 때문에 이해하기 쉽습니다. 당신은 플로팅 슬롯에 self.curve을 재정의

  • :

    두 가지 모자는 프로그램에서 아무 의미가 없습니다합니다.

  • 버튼을 누르면 플롯 슬롯이 호출됩니다. 대신 버튼 누름이 스레드를 시작해야합니다.

나는 정정했다.

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


class MyThread(QtCore.QThread): 
    signal = QtCore.pyqtSignal(object) 
    def __init__(self, parent=None): 
     super(MyThread, self).__init__(parent=parent) 
     self.data = [0] 

    def __del__(self): 
     self.exiting = True 
     self.wait() 

    def run(self): 
     while True: 
      self.data.append(random.random()) 
      self.signal.emit(self.data) 
      time.sleep(0.1) 


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


    def plotter(self, data): 
     self.curve.setData(data) 

    def start(self): 
     self.myThread.start() 
     self.myThread.signal.connect(self.plotter) 


class MainWindow(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     self.centralwidget = QtGui.QWidget(self) 
     self.setCentralWidget(self.centralwidget) 
     self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) 
     self.login_widget_1 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_1) 
     self.login_widget_2 = LoginWidget(self) 
     self.horizontalLayout.addWidget(self.login_widget_2) 
     self.setCentralWidget(self.centralwidget) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    w = MainWindow() 
    w.show() 
    sys.exit(app.exec_())