PyQt5实战:用QtDesigner设计计算器UI并用PyUIC转换为Python代码

张开发
2026/4/20 23:09:53 15 分钟阅读

分享文章

PyQt5实战:用QtDesigner设计计算器UI并用PyUIC转换为Python代码
本文是上篇《PyQt5 入门实战安装、QtDesigner 设计与 PyUIC 转换完整指南》的续篇。上篇完成了环境搭建和工具配置本篇直接上手实战——用 Qt Designer 设计一个简易计算器界面通过 PyUIC 转换代码再编写业务逻辑完整跑通从设计到运行的全流程。环境Python 3.9 PyQt5 5.15.4 PyCharm一、项目结构总览本次计算器项目包含三个核心文件设计计算器/ ├── untitled.ui # Qt Designer 保存的界面描述文件XML 格式 ├── untitled.py # PyUIC 自动生成的 UI 类勿手动修改 └── main.py # 手动编写的业务逻辑 程序入口效果图三个文件职责分离untitled.ui由 Qt Designer 负责描述界面长什么样untitled.py由 PyUIC 负责把.ui翻译成 Python 类main.py由开发者负责继承 UI 类并绑定业务逻辑二、Qt Designer 界面设计2.1 本例用到的控件从截图中的 Widget Box 可以看到Qt Designer 左侧控件库的常用分类控件分类本例用途Push ButtonButtons数字键 0-9、运算符 ±*/、等号、清空共 17 个按钮Text EditInput Widgets标题显示框textEdit和表达式输入/结果显示框textEdit_2Line EditInput Widgets单行文本框本例未使用但常用于密码/搜索框LabelDisplay Widgets静态文字/图片显示本例未使用本例全程只用了Push Button和Text Edit两种控件简单高效。2.2 界面布局结构计算器界面由以下层次组成MainWindow主窗口1297×949 ├── textEdit标题框显示简易计算器28pt 大字居中对齐 ├── widgetVBoxLayout 容器位置 270,120大小 499×261 │ ├── textEdit_2表达式输入/结果显示区 │ └── verticalLayout垂直布局 │ ├── horizontalLayout第1行1 2 3 - │ ├── horizontalLayout_2第2行4 5 6 * / │ └── horizontalLayout_3第3行7 8 9 0 └── pushButton_16清空按钮独立于 widget 外布局设计要点数字和运算符按钮用HBoxLayout水平布局排成3行每行5个三行用VBoxLayout垂直布局自动均匀分配高度清空按钮放在 widget 外单独定位避免影响整体布局2.3 在 Qt Designer 中操作步骤启动 Qt DesignerPyCharm → 工具 → 外部工具 → QtDesigner选择 Main Window 模板点击创建拖入 Text Edit从左侧 Widget Box → Input Widgets → Text Edit拖到画布顶部在属性编辑器中设置 HTML 内容为简易计算器28pt居中拖入容器 Widget拖一个 Widget 到画布中间右键 → 布局 → 垂直布局拖入第二个 Text Edit放到 widget 中作为表达式输入框添加三行按钮每行先拖5个 Push Button全选后右键 → 布局 → 水平布局设置按钮文字在属性编辑器中修改text属性依次设置为 1~9、0、、-、*、/、添加清空按钮拖一个 Push Button 到 widget 外设置 text 为清空调整字号为 18pt 加粗保存CtrlS 保存为untitled.ui三、PyUIC 转换 .ui 为 .py3.1 转换操作保存完untitled.ui后在 PyCharm 项目面板中右键untitled.ui选择外部工具→PyUIC等待几秒自动在同目录生成untitled.py3.2 生成的 untitled.py 代码解析PyUIC 生成的文件包含一个Ui_MainWindow类核心有两个方法setupUi() — 创建所有控件classUi_MainWindow(object):defsetupUi(self,MainWindow):# 1. 设置主窗口尺寸MainWindow.setObjectName(MainWindow)MainWindow.resize(1297,949)# 2. 创建标题文本框绝对定位self.textEditQtWidgets.QTextEdit(self.centralwidget)self.textEdit.setGeometry(QtCore.QRect(320,10,381,87))# 3. 创建清空按钮绝对定位 大号粗体字self.pushButton_16QtWidgets.QPushButton(self.centralwidget)self.pushButton_16.setGeometry(QtCore.QRect(450,410,121,51))fontQtGui.QFont()font.setPointSize(18)font.setBold(True)self.pushButton_16.setFont(font)# 4. 创建 widget 容器VBoxLayoutself.widgetQtWidgets.QWidget(self.centralwidget)self.widget.setGeometry(QtCore.QRect(270,120,499,261))self.verticalLayout_2QtWidgets.QVBoxLayout(self.widget)# 5. 在 widget 内创建表达式框self.textEdit_2QtWidgets.QTextEdit(self.widget)self.verticalLayout_2.addWidget(self.textEdit_2)# 6. 创建三行按钮HBoxLayout × 3self.horizontalLayoutQtWidgets.QHBoxLayout()self.pushButton_1QtWidgets.QPushButton(self.widget)self.horizontalLayout.addWidget(self.pushButton_1)# ... 共 15 个数字/运算符按钮# 7. 末尾绑定所有信号槽重点self.pushButton_16.clicked.connect(self.textEdit_2.clear)self.pushButton_15.clicked.connect(MainWindow.result)# ...retranslateUi() — 设置控件文字defretranslateUi(self,MainWindow):_translateQtCore.QCoreApplication.translate# 标题框 HTML 内容self.textEdit.setHtml(_translate(MainWindow,...span stylefont-size:28pt;简易计算器/span...))# 各按钮文字self.pushButton_16.setText(_translate(MainWindow,清空))self.pushButton_1.setText(_translate(MainWindow,1))self.pushButton_2.setText(_translate(MainWindow,2))# ... 依次设置所有按钮self.pushButton_15.setText(_translate(MainWindow,))注意文件头部的注释明确警告WARNING: Any manual changes made to this file will be lost when pyuic5 is run again.不要在 untitled.py 中写任何业务代码否则下次重新生成会全部丢失四、信号槽连接详解PyUIC 在setupUi()末尾自动生成了所有信号槽连接# untitled.py setupUi() 末尾 —— 信号槽自动连接self.pushButton_16.clicked.connect(self.textEdit_2.clear)# 清空按钮self.pushButton_15.clicked.connect(MainWindow.result)# 计算结果self.pushButton_10.clicked.connect(MainWindow.chu)# / 除法self.pushButton_5.clicked.connect(MainWindow.jian)# - 减法self.pushButton_9.clicked.connect(MainWindow.cheng)# * 乘法self.pushButton_4.clicked.connect(MainWindow.jia)# 加法# 数字键 0-9 全部连接同一个 put 函数self.pushButton_1.clicked.connect(MainWindow.put)self.pushButton_2.clicked.connect(MainWindow.put)# ...self.pushButton_14.clicked.connect(MainWindow.put)信号槽连接规律清空→textEdit_2.clearQt 内置槽无需手写运算符→ 各自对应的jia / jian / cheng / chu方法数字 0-9→ 全部连接put方法用sender()区分是哪个按钮五、main.py 业务逻辑详解fromPyQt5importQtCore,QtGui,QtWidgetsfromPyQt5.QtWidgetsimportQMainWindow,QMessageBoxfromuntitledimportUi_MainWindow# 导入 PyUIC 生成的 UI 类importsysclassPyQtMainEntry(QMainWindow,Ui_MainWindow):# 多重继承窗口功能 UI 结构def__init__(self):super().__init__()self.setupUi(self)# 调用 UI 类的 setupUi完成所有控件创建和信号槽绑定# ———— 数字输入0-9 共用同一个槽函数 ————defput(self):btn_textself.sender().text()# 关键获取点击按钮的文字1/2/.../0current_textself.textEdit_2.toPlainText()self.textEdit_2.setPlainText(current_textbtn_text)# 追加字符# ———— 四则运算符 ————defjia(self):current_textself.textEdit_2.toPlainText()self.textEdit_2.setPlainText(current_text)defjian(self):current_textself.textEdit_2.toPlainText()self.textEdit_2.setPlainText(current_text-)defcheng(self):current_textself.textEdit_2.toPlainText()self.textEdit_2.setPlainText(current_text*)defchu(self):current_textself.textEdit_2.toPlainText()self.textEdit_2.setPlainText(current_text/)# ———— 计算结果 ————defresult(self):try:expressionself.textEdit_2.toPlainText()# 读取当前表达式resstr(eval(expression))# eval 直接计算字符串表达式self.textEdit_2.setPlainText(res)# 把结果写回文本框exceptExceptionase:QMessageBox.warning(self,错误,表达式无效)# 弹出警告框self.textEdit_2.clear()# 清空错误输入if__name____main__:appQtWidgets.QApplication(sys.argv)windowPyQtMainEntry()window.show()sys.exit(app.exec_())关键技术点解析1. 多重继承classPyQtMainEntry(QMainWindow,Ui_MainWindow):同时继承两个类QMainWindow提供窗口的关闭/最大化/最小化等原生功能Ui_MainWindow提供 setupUi() 方法把所有控件安装到窗口上2. sender() 的妙用defput(self):btn_textself.sender().text()# 谁触发了信号谁就是 sender14 个数字按钮共用put()一个函数。self.sender()返回触发信号的对象即被点击的按钮再调用.text()获取按钮显示的文字“1”/“2”/…/“0”无需写 14 个重复函数代码极简。3. eval() 计算表达式resstr(eval(expression))eval()把字符串当 Python 表达式执行12*3会按数学优先级计算得 7。用try-except包裹防止非法输入崩溃。注意eval()在生产环境中存在安全风险学习和本地工具使用没有问题面向公网的应用应使用专门的表达式解析库如ast.literal_eval或mathparser替代。六、完整开发流程回顾Step 1 Qt Designer 拖拽设计界面 ↓ 保存为 untitled.ui Step 2 PyCharm 右键 untitled.ui → 外部工具 → PyUIC ↓ 自动生成 untitled.py含 Ui_MainWindow 类 Step 3 新建 main.py继承 Ui_MainWindow class PyQtMainEntry(QMainWindow, Ui_MainWindow) Step 4 在 __init__ 中调用 self.setupUi(self) 控件和信号槽全部就位 Step 5 在 main.py 中补充槽函数put/jia/jian/cheng/chu/result Step 6 python main.py 运行七、总结文件生成方式内容可手动修改untitled.uiQt Designer 拖拽保存XML 格式界面描述可以但建议在 Designer 中修改untitled.pyPyUIC 自动生成Ui_MainWindow类不要修改重新运行 PyUIC 会覆盖main.py手动编写业务逻辑 程序入口自由修改本例核心思想Qt Designer 只管界面长什么样PyUIC 只管把界面翻译成 Pythonmain.py 只管按钮按下后发生什么三者职责分离互不干扰这正是 Qt 设计器工作流最大的优势。系列导航上一篇PyQt5 入门实战安装、QtDesigner 设计与 PyUIC 转换完整指南本篇PyQt5 实战 — 用 Qt Designer 设计计算器 UI 并用 PyUIC 转换为 Python 代码只管把界面翻译成 Pythonmain.py 只管按钮按下后发生什么

更多文章