当前位置: 代码迷 >> python >> 跨类的变量以在 PyQt GUI 中缩放绘图
  详细解决方案

跨类的变量以在 PyQt GUI 中缩放绘图

热度:94   发布时间:2023-06-13 14:16:53.0

我正在制作一个 GUI,它有几个用户输入框和一个图,它将使用输入框中的因子来缩放数据。 GUI 将需要一个应用按钮和一个导出按钮。 我使用 PyQt5 作为 GUI 和 Matplotlib 进行绘图。 我的方法是为绘图和输入框创建单独的 QWidget,并将它们绑定到第三个 QMainWindow 中。

如何获得应用按钮以将 3 个变量发送到主类和绘图类? 是否有可能在一个类中发生所有这些以简化我的变量的工作方式?

import sys
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from PyQt5.QtWidgets import *
from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class AppForm(QWidget):

    def __init__(self):
        # Initialize the object as a QWidget and
        # set its title and minimum width
        QWidget.__init__(self)
        self.setWindowTitle('Input')
        self.setMinimumWidth(400)

        # Create the QVBoxLayout that lays out the whole form
        self.layout = QVBoxLayout()

        # Create the form layout that manages the labeled controls
        self.form_layout = QFormLayout()

        self.aFactor = QLineEdit(self)
        self.mFactor = QLineEdit(self)
        self.cZone = QLineEdit(self)

        self.form_layout.addRow('AFactor', self.aFactor)
        self.form_layout.addRow('MFactor', self.mFactor)
        self.form_layout.addRow('CZone', self.cZone)

        self.layout.addLayout(self.form_layout)
        self.button_box = QHBoxLayout()
        self.button_box.addStretch(1)

        self.apply_button = QPushButton("Apply", self)
        self.output_button = QPushButton("Output", self)

        self.button_box.addWidget(self.apply_button)
        self.button_box.addWidget(self.output_button)
        self.layout.addLayout(self.button_box)
        self.setLayout(self.layout)

        self.apply_button.clicked.connect(self.applyButton)

    def applyButton(self):
        self.af = self.aFactor
        self.mf = self.mFactor
        self.cz = self.cZone

        print self.af.text(), self.mf.text(), self.cz.text()

class MyMplCanvas(FigureCanvas):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    def __init__(self, parent=None, width=5, height=4, dpi=100, title='title'):
        self.title = title
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        fig.suptitle(title)

        # We want the axes cleared every time plot() is called
        self.axes.hold(False)

        self.compute_initial_figure()


        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass


class MyStaticMplCanvas(MyMplCanvas):
    """Simple canvas with a sine plot."""
    def compute_initial_figure(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2*pi*t)
        self.axes.plot(t, s)
        self.axes.set_ylabel('label1')
        self.axes.set_xlabel('label')
        self.axes.grid(True)



class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")
        self.setMinimumWidth(800)
        self.setMinimumHeight(600)

        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.help_menu = QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)

        self.help_menu.addAction('&About', self.about)

        self.main_widget = QWidget(self)

        l = QVBoxLayout(self.main_widget)
        form = AppForm()
        sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100, title='Title 1')
        l.addWidget(form)
        l.addWidget(sc)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        #self.statusBar().showMessage("Cool", 2000

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

    def about(self):
        QMessageBox.about(self, "About",)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    aw = ApplicationWindow()
    aw.setWindowTitle("PyQt5 Matplot Example")
    aw.show()
    #sys.exit(qApp.exec_())
    app.exec_()

这里有几个选项:

(a) 执行主类中的工作:不将AppForm的按钮连接到AppForm中的方法, AppFormApplicationWindow执行相同的操作。

self.form = AppForm()
self.sc = MyStaticMplCanvas(....)
self.form.apply_button.clicked.connect(self.applyButton)

def applyButton(self):
    tx = self.form.aFactor.text()
    # do something with tx
    # e.g. call a method from MplCanvas
    self.sc.someMethod(tx)

(b) 使用信号和槽:AppForm创建一个信号 单击按钮后, applyButton可能会发出带有相关内容的信号。 ApplicationWindow ,将该信号连接到可以以某种方式使用提供的数据的方法。 您也可以将其直接连接到MplCanvas的方法。

class AppForm(QWidget):
    mysignal = pyqtSignal(object)
    def __init__(self):
        ....
        self.apply_button.clicked.connect(self.applyButton)

    def applyButton(self):
        self.mysignalemit((self.aFactor.text(),self.mFactor.text(), self.cZone()) )

class ApplicationWindow(QMainWindow):
    def __init__(self):
        ....
        self.form = AppForm()
        self.sc = MyStaticMplCanvas(....)
        self.form.mysignal.connect(self.useButtonResults)
        self.form.mysignal.connect(self.sc.someMethod)

    def useButtonResults(self, obj):
        a,b,c = obj
        # do something with a, b, c

(c) 使用一个类来做所有事情:只需将所有东西放在一个类中,然后做任何你喜欢做的事情。