2017-01-22 4 views
1

Помимо основного класса Window, я определил новый класс (test_graph_Data), который будет рисовать график с помощью matplotlib. Во избежание проблем с будильником «QPixmap: небезопасно использовать pixmaps за пределами потока GUI», я определил новый класс test_graph_Data, который выдаст сигнал основному классу для рисования графика, но есть некоторые проблемы, чтобы испустить сигналы ... Посмотрите на код ниже:PyQt, QThread, рисовать график matplotlib с вопросом QThread

Когда я запустил код, я получил предупреждение: AttributeError: объект «PyQt4.QtCore.pyqtSignal» не имеет атрибута «connect»!

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

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

Смежные вопросы