单击按钮后在 PyQt 窗口中显示 PyQt 图表
Posted
技术标签:
【中文标题】单击按钮后在 PyQt 窗口中显示 PyQt 图表【英文标题】:Displaying a PyQt Chart in a PyQt Window after a button click 【发布时间】:2021-12-18 19:02:05 【问题描述】:我正在使用 PyQT 和 QtDesigner 为大学项目构建一个简单的(!)GUI 应用程序。
主窗口显示一些简单的标签和文本框(工资、养老金缴款百分比、询问用户是否有学生贷款)。单击并单击“计算”按钮后,其想法是 QtChart(现在是简单的饼图)将在表单底部显示一些预定义的空间。我在表单底部添加了一个 Widget,可以正确执行所有计算并绘制图表,但我不知道如何设置 Widget 的属性以便它显示图表。
我观看了大量教程并阅读了大量文章,但似乎找不到以相同方式执行此操作的示例。一个不太理想的选择是启动一个显示图表的新窗口,但实际上我想在我的 gui 中的预定义空间中显示,以便我可以完全控制 UI 体验。
我在下面添加了相关的代码部分,如果有人能告诉我哪里出错了,我将不胜感激!非常感谢。
# main.py
import sys
import gui
# app_choice = 'mail'
app_choice = 'salary'
# app_choice = 'todo_list'
if __name__ == "__main__":
app = gui.QtWidgets.QApplication(sys.argv)
win = gui.QtWidgets.QMainWindow()
if app_choice == 'mail':
ui = gui.Ui_MainWindowMail()
elif app_choice == 'salary':
ui = gui.Ui_MainWindowTax()
elif app_choice == 'todo_list':
raise ValueError('This app is still being built!')
else:
raise ValueError('An incorrect app choice was made.')
ui.setupUi(win)
win.show()
sys.exit(app.exec_())
# gui.py
from PyQt5 import QtCore, QtGui, QtWidgets
import mail
import tax
from PyQt5.QtWidgets import *
from PyQt5.QtChart import QChart, QChartView, QPieSeries, QPieSlice
from PyQt5.QtGui import QPainter, QPen, QFont
from PyQt5.QtCore import Qt
class Ui_MainWindowMail(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(362, 255)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.btn_send = QtWidgets.QPushButton(self.centralwidget)
self.btn_send.setGeometry(QtCore.QRect(250, 190, 81, 31))
self.btn_send.setObjectName("btn_send")
self.btn_send.clicked.connect(self.btn_send_click) # Call the 'clicked' function when button is clicked
self.lbl_to = QtWidgets.QLabel(self.centralwidget)
self.lbl_to.setGeometry(QtCore.QRect(30, 20, 51, 21))
self.lbl_to.setObjectName("lbl_to")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(30, 40, 111, 31))
self.label.setObjectName("label")
self.txt_to = QtWidgets.QLineEdit(self.centralwidget)
self.txt_to.setGeometry(QtCore.QRect(120, 20, 211, 20))
self.txt_to.setObjectName("txt_to")
self.txt_msg = QtWidgets.QTextEdit(self.centralwidget)
self.txt_msg.setGeometry(QtCore.QRect(120, 50, 211, 131))
self.txt_msg.setDocumentTitle("")
self.txt_msg.setObjectName("textEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 362, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Send Email Tool"))
self.btn_send.setText(_translate("MainWindow", "Send Email"))
self.lbl_to.setText(_translate("MainWindow", "Send to:"))
self.label.setText(_translate("MainWindow", "Email message:"))
def btn_send_click(self):
if self.txt_to.text() != "" and self.txt_msg.toPlainText() != "":
mail.send_mail(self.txt_to.text(), self.txt_msg.toPlainText())
self.txt_to.setText("")
self.txt_msg.setText("")
qm = QtWidgets.QMessageBox()
qm.setWindowTitle("Send Email Tool")
qm.setText("Email sent")
qm.exec()
else:
qm = QtWidgets.QMessageBox()
qm.setWindowTitle("Send Email Tool - ERROR")
qm.setText("Some information is missing. Please check and try again.")
qm.exec()
class Ui_MainWindowTax(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(465, 650)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label_title = QtWidgets.QLabel(self.centralwidget)
self.label_title.setGeometry(QtCore.QRect(20, 10, 371, 21))
font = QtGui.QFont()
font.setPointSize(12)
self.label_title.setFont(font)
self.label_title.setAlignment(QtCore.Qt.AlignCenter)
self.label_title.setObjectName("label_title")
self.label_salary = QtWidgets.QLabel(self.centralwidget)
self.label_salary.setGeometry(QtCore.QRect(30, 60, 240, 21))
self.label_salary.setObjectName("label_salary")
self.txt_salary = QtWidgets.QLineEdit(self.centralwidget)
self.txt_salary.setGeometry(QtCore.QRect(270, 60, 161, 20))
self.txt_salary.setObjectName("txt_salary")
self.label_pension = QtWidgets.QLabel(self.centralwidget)
self.label_pension.setGeometry(QtCore.QRect(30, 100, 221, 16))
self.label_pension.setObjectName("label_pension")
self.spin_pension = QtWidgets.QSpinBox(self.centralwidget)
self.spin_pension.setGeometry(QtCore.QRect(270, 100, 51, 22))
self.spin_pension.setObjectName("spin_pension")
self.combo_student_loan = QtWidgets.QComboBox(self.centralwidget)
self.combo_student_loan.setGeometry(QtCore.QRect(270, 140, 69, 22))
self.combo_student_loan.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
self.combo_student_loan.setEditable(True)
self.combo_student_loan.setObjectName("combo_student_loan")
self.combo_student_loan.addItem("")
self.combo_student_loan.addItem("")
self.label_student_loan = QtWidgets.QLabel(self.centralwidget)
self.label_student_loan.setGeometry(QtCore.QRect(30, 140, 211, 16))
self.label_student_loan.setObjectName("label_student_loan")
self.button_calculate = QtWidgets.QPushButton(self.centralwidget)
self.button_calculate.setGeometry(QtCore.QRect(30, 190, 401, 41))
self.button_calculate.setObjectName("button_calculate")
self.button_calculate.clicked.connect(self.button_calculate_click) # Call the 'clicked' function when button is clicked
self.widget_chart = QWidget(self.centralwidget)
self.widget_chart.setObjectName("widget_chart")
self.widget_chart.setGeometry(QtCore.QRect(40, 240, 381, 331))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 465, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Salary Calculator"))
self.label_title.setText(_translate("MainWindow", "Salary Calculator"))
self.label_salary.setText(_translate("MainWindow", "Please enter you gross salary to the nearest £:"))
self.label_pension.setText(_translate("MainWindow", "Please select your pension contribution (%):"))
self.combo_student_loan.setCurrentText(_translate("MainWindow", "No"))
self.combo_student_loan.setItemText(0, _translate("MainWindow", "Yes"))
self.combo_student_loan.setItemText(1, _translate("MainWindow", "No"))
self.label_student_loan.setText(_translate("MainWindow", "Do you have a student loan?"))
self.button_calculate.setText(_translate("MainWindow", "Calculate!"))
def button_calculate_click(self):
# Get values entered into the form
salary = self.txt_salary.text()
salary = int(salary)
student_loan_flag = self.combo_student_loan.currentText()
pension_contribution = self.spin_pension.value()
# Calculate income tax deductions
income_tax = tax.calculate_income_tax(salary)
ni = salary * 0.01
# Calculate pension deduction
pension = salary * (pension_contribution / 100)
# Calculate student loan deduction
student_loan_pay_threshold = 19895 # Plan 1 repayment threshold. ToDo: Update to work for all loan plans
if student_loan_flag == 'No' or salary < student_loan_pay_threshold:
student_loan = 0
else:
student_loan = (salary - student_loan_pay_threshold) * 0.09
# Calculate Net Pay
net_pay = salary - income_tax - ni - pension - student_loan
# Create PyQt chart
series = QPieSeries()
series.setHoleSize(0.1)
series.append("Income Tax", income_tax)
series.append("NI", ni)
series.append("Pension", pension)
series.append("Student Loan", student_loan)
series.append("Net Pay", net_pay)
chart = QChart()
chart.addSeries(series)
chart.setAnimationOptions(QChart.SeriesAnimations)
chart.setTheme(QChart.ChartThemeLight)
chartview = QChartView(chart)
chartview.setRenderHint(QPainter.Antialiasing)
#self.widget_chart.setLayout(chartview)
【问题讨论】:
你可以尝试创建一个包含图表视图的中间布局并设置它,不确定它是否可以工作 【参考方案1】:将图表小部件添加到您的布局中,然后根据需要使用其 QWidget show() hide() 插槽。
【讨论】:
以上是关于单击按钮后在 PyQt 窗口中显示 PyQt 图表的主要内容,如果未能解决你的问题,请参考以下文章
在现有主窗口上显示在 PyQt GUI 上选择组合框选项的图表
PyQT5 与 matplotlib 图,事件循环已经在运行