2017-01-22 66 views
1

在主類窗口旁邊,我定義了新類(test_graph_Data),它將使用matplotlib繪製圖形。爲了避免報警問題「QPixmap:在GUI線程之外使用pixmaps是不安全的」,我已經定義了新的類test_graph_Data,它會向主類發出信號以繪製圖形,但是有一些問題需要發出信號...看看下面的代碼:PyQt,QThread,繪製帶有QThread問題的matplotlib圖形

當我運行代碼,我得到了警告:AttributeError:「PyQt4.QtCore.pyqtSignal」對象沒有屬性'連接'!

import sys, time 
from PyQt4 import QtGui, QtCore 
import matplotlib.pyplot as plt 

class Window(QtGui.QMainWindow): 

    def __init__(self): 
     super(Window, self).__init__() 
     self.setGeometry(50, 50, 120, 90) 
     self.home() 

    def home(self): 
     self.test = QtGui.QPushButton("Test", self) 
     self.test.clicked.connect(self.test1_function) 
     self.test.move(10,20) 
     self.show() 

    def test1_function(self): 
     self.get_thread = test_graph_Data() 
     self.connect(self.get_thread, QtCore.SIGNAL("finished()"),self.done_test1_function) 
     self.get_thread.start() 

    def done_test1_function(self): 
     print 'Graph is displayed!' 

class test_graph_Data(QtCore.QThread) : 
    def __init__(self): 
     QtCore.QThread.__init__(self) 

    def __del__(self): 
     self.wait() 

    def graph_data(self): 
     start = time.time() 
     b = [1,0,1,0,1,0,1,1,1,1,0,1,0,1] 
     plt.ion() 
     fig1 = plt.figure() 
     ax1 = fig1.add_subplot(111) 
     ax1.plot(b, 'b') 
     end = time.time() 
     print end - start 

    def run(self): 
     top_post = self.graph_data() 

def main(): 
    app = QtGui.QApplication(sys.argv) 
    GUI = Window() 
    GUI.show() 
    sys.exit(app.exec_()) 


if __name__ == '__main__' : 
    main() 
+0

您不能在主線程(GUI線程)以外的其他線程中顯示任何圖形。 你想圖什麼? – eyllanesc

+0

@eyllanesc就是這一點。在初始化test_graph_Data類中的圖之後,我想向主線程發送信號以顯示圖...例如數組b = [1,0,1,0,1,0,1,1,1,1,0 ,1,0,1]就像它在代碼中所述。最主要的是該圖應該在其他中初始化,而不是在主線程中。 –

回答

1

必須使用線程來處理數據,而不是圖表。在這個例子中,我已經讓你的列表旋轉。您必須創建一個信號,與主線程通信數據已準備好進行更新。在GUI中,您必須將該信號與更新圖形的函數連接起來。

import sys 
import time 
import matplotlib as mpl 
mpl.use("QT4Agg") 
import matplotlib.pyplot as plt 
from PyQt4 import QtGui, QtCore 


class test_graph_Data(QtCore.QThread): 
    updated = QtCore.pyqtSignal(list) 
    running = True 

    def __init__(self, parent=None): 
     QtCore.QThread.__init__(self, parent) 
     self.b = [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1] 

    def run(self): 
     while self.running: 
      # rotate list 
      self.b = self.b[1:] + [self.b[0]] 
      self.updated.emit(self.b) 
      time.sleep(0.1) 


class Window(QtGui.QMainWindow): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.setGeometry(50, 50, 120, 90) 
     self.home() 

    def home(self): 
     self.test = QtGui.QPushButton("Test", self) 
     self.test.clicked.connect(self.test1_function) 
     self.test.move(10, 20) 
     self.show() 

    def test1_function(self): 
     self.get_thread = test_graph_Data(self) 
     self.get_thread.finished.connect(self.done_test1_function) 
     self.get_thread.updated.connect(self.graph_data) 
     plt.ion() 
     fig1 = plt.figure() 
     self.ax1 = fig1.add_subplot(111) 
     self.get_thread.start() 

    def done_test1_function(self): 
     print('Graph is displayed!') 

    def graph_data(self, data): 
     self.ax1.clear() 
     self.ax1.plot(data, 'b') 

    def closeEvent(self, event): 
     self.get_thread.running = False 
     self.get_thread.wait() 


def main(): 
    app = QtGui.QApplication(sys.argv) 
    GUI = Window() 
    GUI.show() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 
+0

就是這樣!非常感謝!有一些改進代碼的提示,比如刪除「import matplotlib as mpl mpl.use(」QT4Agg「)」,但你明白了! –

+0

問題是我已經安裝了pyqt4和pyqt5,但是我把那條線與pyqt的版本有問題。 – eyllanesc