2017-01-18 59 views
1

首先對於長度感到抱歉。我想盡可能好地解釋我的問題。我對Python很陌生,試圖使用嵌入在PyQt4中的PyQtGraph製作繪圖應用程序。前幾天我對我的plotting problem得到了一個非常好的答案,下一步是讓兩個PyQtGraphs在同一個PyQt4的CentralWidget中同時繪製小部件。通過與所述鏈接相同的方法,兩個圖都可以正常工作,但GUI無法響應。爲了克服這個問題,我打算使用QThread,爲此,我需要在不同的類中繪製我的繪圖函數。但我有我的變量搞亂,而不能看到:在PyQt4#2中使用PyQtGraph進行實時繪圖

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(Plots.plotter) 
     self.central_widget.addWidget(self.login_widget) 


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) 


class Plots(MainWindow): 

    def print(self): 
     print('hello World') 

    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) 

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

這給了我在Plots.plotter錯誤:

self.data = [0] 
AttributeError: 'bool' object has no attribute 'data' 

如果在主窗口類我替換「按鈕。連接'參數與Plots.print,它工作正常。所以我可以看到我在MainWindow中創建了一個LoginWidget對象,然後Plots從MainWindow繼承,再次調用同一個LoginWidget對象。

我試過了一個建議的解決方案,其中父親(MainWindow)不訪問孩子們的方法(繪圖)。但是,如果從情節,我要打電話,我的目標是把我的線程在班上,我再次得到了同樣的錯誤....

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


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) 


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.central_widget.addWidget(self.login_widget) 


class Plots(MainWindow): 
    def __init__(self, parent=None): 
     super(Plots, self).__init__(parent=parent) 
     self.login_widget.button.clicked.connect(MyThread.plotter) 



class MyThread(MainWindow): 
    def __init__(self, parent=None): 
     super(Aname, self).__init__(parent=parent) 

    def print(self): 
     print('hello World') 

    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) 


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

你的代碼給了我一個不同的錯誤。 'self.login_widget.button.clicked.connect(Plots.plotter)'AttributeError:'function'object has no attribute'__pyqtSignature__' – Trilarion

+0

當你用self.login_widget中的Plots.print替換Plots.plotter時,它是否會給出相同的錯誤。 button.clicked.connect(Plots.plotter)? – Ivy

回答

2

在繼承父親不應該訪問的孩子的方法,繼承和實現與子類中的父項無關的新方法會更好。

定時器版本

import random 
import sys 

import pyqtgraph as pg 
from PyQt4 import QtGui, QtCore 


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) 

    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) 


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_()) 
+0

謝謝,但這並不能解決我的問題。 「我需要在不同的類中繪製我的繪圖函數_」,以便使用QThread。所以,如果我只是創建一個新的類,也從MainWindow繼承,並調用它,我會得到同樣的錯誤。在這種情況下,我不會將我的插槽調用放在我繼承的類(MainWindow)上,但在Plots中,正如您所建議的那樣。 – Ivy

+1

@Ivy 你可以把你想要的圖片? – eyllanesc

+0

我想在同一個小部件中使用兩個按鈕和兩個圖形。每個按鈕都會觸發一個圖形,就像上面的單個圖形示例一樣,並且該應用程序仍然是響應式的,就像上面的單個圖形示例一樣。 – Ivy