問題描述
我正在制作一個 GUI,它有幾個用戶輸入框和一個繪圖,它將使用輸入框中的因子來縮放數據.GUI 將需要一個應用按鈕和一個導出按鈕.我使用 PyQt5 作為 GUI 和 Matplotlib 進行繪圖.我的方法是為繪圖和輸入框創建單獨的 QWidget,并將它們綁定在第三個 QMainWindow 中.
I'm making a GUI which is to have a couple user input boxes and a plot which will use factors in the input boxes to scale data. The GUI will need an apply button and an export button. I am using PyQt5 for the GUI and Matplotlib for the plotting. My approach has been to create separate QWidgets for the plot and the input boxes and tie them together in a third QMainWindow.
我的 GUI 顯示正確
如何獲得應用按鈕以將 3 個變量發送到主類和繪圖類?是否有可能將所有這些都發生在一個類中以簡化我的變量的工作方式?
How can I get the apply button to send the 3 variables across to the main class and to the plotting class? Would it be possible to have all of this happen within one class to simplify how my variables will work?
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
中的方法,而是在 ApplicationWindow
中執行相同操作.
(a) Peform the work in the main class:
Instead of connecting the button in the AppForm
to a method in AppForm
, do the same in the ApplicationWindow
.
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
中創建一個signla.單擊按鈕后,applyButton
可能會發出帶有相關內容的信號.在 ApplicationWindow
中,將該信號連接到可以以某種方式使用所提供數據的方法.也可以直接連接到MplCanvas
的方法.
(b) Use signals and slots:
Create a signla in AppForm
. Once the button is clicked, applyButton
may emit this signal with the relevant content. In ApplicationWindow
connect that signal to a method which can use the supplied data in some way. You can also connect it directly to a method of 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) 使用單個類完成所有操作:只需將所有內容放在一個班級中,然后隨心所欲.
(c) Use a single class to do everything: Just put everything in a single class and do whatever you like.
這篇關于跨類的變量以在 PyQt GUI 中縮放繪圖的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!