Создайте несколько всплывающих графиков с помощью FigureCanvas в PyQt4 - PullRequest
0 голосов
/ 15 мая 2018

Следующий код создает виджет с кнопкой и индикатором выполнения.Когда кнопка нажата, а индикатор выполнения достигает 100%, отображаются 3 графика (по Matplotlib.pyplot):

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import matplotlib.pyplot as plt
import pandas as pd

class App(QMainWindow):

    def __init__(self):
        super(App, self).__init__()
        self.setGeometry(500, 300, 820, 350)
        self.setWindowTitle("Program")

        #Buttons
        btnposx = 30
        btnposy = 50

        self.btn4 = QPushButton('Load', self)
        self.btn4.move(btnposx,btnposy+220)       
        self.btn4.released.connect(self.thread)

        #ProgressBar
        self.pb = QProgressBar(self)
        self.pb.move(btnposx+150,btnposy+220)
        self.pb.resize(470,27)        

        self.show()

    @pyqtSlot(float)
    def load(self, val):
        self.pb.setValue(val)

    @pyqtSlot(object)
    def plot(self, pq):
        pq.plot(grid = 1)
        plt.show()

    def thread(self):
        self.thread_ = Thread()
        self.thread_.pb_signal.connect(self.load, Qt.QueuedConnection)
        self.thread_.plot_signal.connect(self.plot, Qt.QueuedConnection)
        self.thread_.start()

class Thread(QThread):
    pb_signal = pyqtSignal(float)
    plot_signal = pyqtSignal(object)

    def __init__(self, *args, **kwargs):
        QThread.__init__(self, *args, **kwargs)

    def __del__(self):
        self.wait()

    @pyqtSlot()    
    def run(self):       
        val = 0
        self.pb_signal.emit(20)
        l = range(50000000)
        for i in l:
            val += 1
        self.pb_signal.emit(60)
        self.pb_signal.emit(100)
        pq = pd.DataFrame(data = {'col1':[1,2,3,4,5,6], 'col2':[6,5,4,3,2,1]})
        self.plot_signal.emit(pq)
        self.plot_signal.emit(pq)
        self.plot_signal.emit(pq)        
        return

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

Как мне сделать то же самое с FigureCanvas?Я не хочу делать одно окно, в котором 3 графика встроены, но 3 отдельные цифры.Информации о том, как использовать FigureCanvas в Интернете, очень мало.

1 Ответ

0 голосов
/ 15 мая 2018

FigureCanvas - это специализированный QWidget, который может содержать рисунок matplotlib, и на этом рисунке вы можете создавать графики, поэтому решение заключается в создании одного для каждого выпуска, в дополнение к этому функции построения графиков имеют дополнительный аргумент, который получаетоси, на которых он будет нарисован, поэтому вы должны передать оси, созданные внутри Рис.:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import pandas as pd
from matplotlib.backends.backend_qt4agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure

class App(QMainWindow):

    def __init__(self):
        super(App, self).__init__()
        self.setGeometry(500, 300, 820, 350)
        self.setWindowTitle("Program")

        #Buttons
        btnposx = 30
        btnposy = 50

        self.btn4 = QPushButton('Load', self)
        self.btn4.move(btnposx,btnposy+220)       
        self.btn4.released.connect(self.thread)

        #ProgressBar
        self.pb = QProgressBar(self)
        self.pb.move(btnposx+150,btnposy+220)
        self.pb.resize(470,27)        
        self.canvas = []
        self.show()

    @pyqtSlot(float)
    def load(self, val):
        self.pb.setValue(val)

    @pyqtSlot(object)
    def plot(self, pq):
        cv = FigureCanvas(Figure(figsize=(5, 3)))
        ax = cv.figure.subplots()
        pq.plot(grid = 1, ax=ax)
        cv.show()
        # avoid garbage collector
        self.canvas.append(cv)

    def thread(self):
        self.thread_ = Thread()
        self.thread_.pb_signal.connect(self.load, Qt.QueuedConnection)
        self.thread_.plot_signal.connect(self.plot, Qt.QueuedConnection)
        self.thread_.start()

class Thread(QThread):
    pb_signal = pyqtSignal(float)
    plot_signal = pyqtSignal(object)

    def __del__(self):
        self.wait()

    @pyqtSlot()    
    def run(self):       
        val = 0
        self.pb_signal.emit(20)
        l = range(50000000)
        for i in l:
            val += 1
        self.pb_signal.emit(60)
        self.pb_signal.emit(100)
        pq = pd.DataFrame(data = {'col1':[1,2,3,4,5,6], 'col2':[6,5,4,3,2,1]})
        self.plot_signal.emit(pq)
        self.plot_signal.emit(pq)
        self.plot_signal.emit(pq)        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

Примечание: только список был создан для предотвращения удаления графиков сборщиком мусора

...