ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python编写可视化界面的详细教程(Python+PyCharm+PyQt)

Python编写可视化界面的详细教程(Python+PyCharm+PyQt) 前言先纠正标题里一个容易误导的说法这里的「可视化界面」指的是图形用户界面GUIGraphical User Interface也就是带窗口、按钮、输入框的那种桌面程序不是数据可视化把数据画成图表。两者中文里都叫「可视化」但技术栈完全不同。本文讲的是前者。另外要说明PyCharm 在这套组合里只是编辑器它不参与界面渲染。用 VS Code、IDLE 甚至记事本写 PyQt 程序都没问题。PyCharm 的价值在于能方便地指定项目解释器、能一步运行脚本、能调试信号回调。本文会顺带说一句工程配置但重点在 PyQt 本身。还有一件事必须先讲清楚否则可能涉及法律问题PyQt 和 PySide 的许可证不同。PyQt 由 Riverbank 开发采用 GPL v3 加商业授权双许可官方文档明确写着 PyQt6「不像大多数 Qt 组件那样提供 LGPL」。这意味着如果你用 GPL 版的 PyQt 发布闭源商业软件会违反许可。而 PySide 是 Qt 官方的 Python 绑定采用 LGPL闭源项目更友好。选型时这一点比 API 差异重要得多。一、选型三个包怎么选包名提供方许可证安装备注PyQt5RiverbankGPL v3 / 商业pip install PyQt5老项目多exec_()写法PyQt6RiverbankGPL v3 / 商业pip install PyQt6当前主推要求 Python 3.9PySide6Qt 官方LGPL / GPLpip install PySide6API 与 PyQt 高度相似需要留意的是PyQt6 要求 Python 3.9 或以上官方文档原文是「PyQt6 requires Python v3.9 or later」。三者 API 大体同源很多代码改改 import 就能互转但版本间的写法差异尤其是执行方法名和枚举必须区分清楚后面单独讲。二、最小可运行窗口与常用控件PyQt 程序的骨架永远是四步创建QApplication、创建窗口、show()、进入事件循环。下面是 PyQt6 的写法# 适用于 Python 3.9需先安装pip install PyQt6import sysfrom PyQt6.QtWidgets import (QApplication, QWidget, QLabel,QPushButton, QLineEdit, QVBoxLayout)class MainWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle(我的第一个界面)self.resize(320, 200)layout QVBoxLayout(self) # 竖向布局挂到窗口上self.input QLineEdit()self.input.setPlaceholderText(请输入名字)self.button QPushButton(打招呼)self.output QLabel(等待输入)layout.addWidget(self.input)layout.addWidget(self.button)layout.addWidget(self.output)# 信号与槽按钮被点击时调用 self.on_clickself.button.clicked.connect(self.on_click)def on_click(self):name self.input.text().strip()self.output.setText(f你好{name} if name else 请先输入名字)app QApplication(sys.argv) # 每个程序有且只有一个 QApplicationwindow MainWindow()window.show() # 先 show 再进入事件循环sys.exit(app.exec()) # 启动事件循环退出时把返回码交还系统几个必须理解的细节。第一QApplication是整个程序的入口一个程序只能有一个它负责管理事件循环和全局状态。第二app.exec()会阻塞程序停在这一行处理鼠标、键盘等各种事件直到窗口全部关闭才返回所以window.show()必须写在它前面。第三sys.exit(app.exec())把 Qt 的退出码原样交给操作系统这是官方示例的标准写法。第四布局Layout负责自动排布控件不要用绝对坐标自己摆——窗口一拉伸布局就全乱了。Qt 的控件widget都从QWidget派生。常用控件包括控件类名用途标签QLabel显示文字或图片按钮QPushButton点击触发动作单行输入QLineEdit输入一行文本多行文本QTextEdit输入或显示多行文本列表QListWidget列表项选择下拉框QComboBox从下拉项里选布局管理器负责把控件摆到窗口里常用的有三种QVBoxLayout竖向排列。QHBoxLayout横向排列。QGridLayout网格排列用addWidget(w, row, col)指定行列。布局可以嵌套外层用QVBoxLayout其中一行的按钮放进一个QHBoxLayout再把这个横向布局addLayout到外层。记住不要手动设控件坐标——setGeometry这类绝对定位在窗口缩放时会立刻暴露问题。三、信号与槽界面的「神经」Qt 最核心的机制是信号与槽signals and slots。官方文档的定义是当某件值得关注的事情发生时会发出一个信号signal槽slot是一个 Python 可调用对象信号连接connect到槽之后信号发出时槽就被调用。发信号的一方不需要知道谁在接收这就实现了界面与逻辑的解耦。# 适用于 Python 3.9需先安装pip install PyQt6self.button.clicked.connect(self.on_click) # 点击信号连到自定义方法self.input.textChanged.connect(self.on_change) # 文本变化时触发self.input.returnPressed.connect(self.on_click) # 回车时触发官方文档列出的信号/槽特性里有几条值得记住一个信号可以连接多个槽一个槽也可以被多个信号连接连接可以是同步的direct也可以是排队的queued还可以跨线程连接。注意connect里传的是函数对象本身不能加小括号——写成self.on_click()会在连接时就把函数执行一次。四、版本差异与工具配置如果你对照网上的老教程可能会发现代码跑不起来。以下是官方列出的主要差异执行方法名官方文档明确「Allexec_()andprint_()methods have been removed」。所以 PyQt6 里写app.exec()而 PyQt5 里是app.exec_()。枚举的作用域PyQt6 里所有具名枚举都变成标准库Enum的子类使用时需要带作用域例如对齐要写Qt.AlignmentFlag.AlignCenterPyQt5 里可以直接写Qt.AlignCenter。信号的定义方式旧式写法与新版写法不同自定义信号需要用pyqtSignal一类机制声明具体以其官方文档的信号章节为准。所以迁移代码时exec_改exec、枚举加作用域是最常见的两处。不确定某个枚举属于哪个类时查官方文档而不是凭印象补。最后说工具侧。PyCharm 只需要做两件事。第一指定项目解释器在项目设置里选择你安装了 PyQt6 的那个解释器虚拟环境更干净否则会出现「命令行能装、PyCharm 里 import 不到」的经典问题。第二配置运行目标右键脚本选运行或新建一个运行配置指向你的入口文件。调试时可以在槽函数里打断点信号触发时会停在断点上——这正是把界面逻辑拆进独立方法的好处。常见坑点忘了创建QApplication。❌ 直接MainWindow().show()报错说没有 QApplication 实例。 ✅ 先app QApplication(sys.argv)且整个程序只创建一次。connect时给函数加了括号。❌self.button.clicked.connect(self.on_click())点击没反应函数在绑定那一刻就被调用了一次。 ✅ 传函数对象connect(self.on_click)。show()写在exec()后面。❌ 先app.exec()再window.show()程序卡在事件循环里窗口不出现。 ✅window.show()必须在进入事件循环之前。照抄 PyQt5 的exec_()。❌ 在 PyQt6 里写app.exec_()提示方法不存在。 ✅ PyQt6 已移除exec_()改用app.exec()。枚举不写作用域。❌ PyQt6 里沿用Qt.AlignCenter报枚举找不到。 ✅ PyQt6 的枚举是Enum子类需要Qt.AlignmentFlag.AlignCenter这样的限定名。用绝对坐标摆控件。❌ 用setGeometry一个个定位置窗口一缩放界面就错位。 ✅ 用QVBoxLayout/QHBoxLayout/QGridLayout自动布局需要伸缩时配合addStretch。在子线程里直接改界面。❌ 耗时任务放主线程界面「未响应」或从子线程直接调用控件方法。 ✅ 耗时任务放子线程通过信号把结果发回主线程更新界面信号可以跨线程连接。忽略许可证差异。❌ 用 GPL 版 PyQt 发布闭源商业软件。 ✅ 先确认 PyQt 是 GPL/商业双许可、PySide 是 LGPL闭源项目通常优先考虑 PySide6具体条款以官方文档为准。总结环节关键 API要点程序入口QApplication(sys.argv)全程序唯一窗口QWidget子类 show()show 要在 exec 之前事件循环app.exec()会阻塞PyQt6 无下划线布局QVBoxLayout/QGridLayout不要绝对定位交互signal.connect(slot)传函数对象不加括号版本差异枚举作用域PyQt6 枚举需限定名许可证GPL / LGPL闭源选型前先确认写 PyQt 界面的心智模型其实很清晰界面是控件树交互是信号与槽程序由事件循环驱动。把这三点想明白剩下的就是查控件文档。最后提醒一句上面的代码都是按官方文档的接口写的但你本机环境里的 PyQt 版本、Python 版本可能不同跑之前请先确认版本遇到 API 差异以 PyQt 官方文档为准。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进