文章目录
- @[toc]
- 1 概述
- 1.1 PySide 能做什么?
- 1.2 PySide 的优点
- 1.3 PySide 的缺点
- 1.4 示例代码(简单窗口)
- 2 环境准备
- 2.1 安装必要软件
- 2.2 修改 pip 源
- 3 PySide2
- 3.1 环境要求
- 3.2 配置PySide2
- 3.3 工具配置
- 4 PySide6
- 4.1 环境
- 4.2 配置PySide6
- 4.3 工具配置
- 4.4 修改pyside6-project lupdate的bug
- 5 工具使用
- 5.1 使用pyside6-project构建工程
- 5.2 创建、打开ui文件
- 5.3 生成翻译文件
- 5.4 修改ts翻译文件
- 6 工程管理脚本
- 7 相关地址
文章目录
- @[toc]
- 1 概述
- 1.1 PySide 能做什么?
- 1.2 PySide 的优点
- 1.3 PySide 的缺点
- 1.4 示例代码(简单窗口)
- 2 环境准备
- 2.1 安装必要软件
- 2.2 修改 pip 源
- 3 PySide2
- 3.1 环境要求
- 3.2 配置PySide2
- 3.3 工具配置
- 4 PySide6
- 4.1 环境
- 4.2 配置PySide6
- 4.3 工具配置
- 4.4 修改pyside6-project lupdate的bug
- 5 工具使用
- 5.1 使用pyside6-project构建工程
- 5.2 创建、打开ui文件
- 5.3 生成翻译文件
- 5.4 修改ts翻译文件
- 6 工程管理脚本
- 7 相关地址
1 概述
通常提到的 PyQt 实际上可以分为 PyQt 和 PySide 两个分支。
PyQt6 和 PySide6 都是基于 Qt 库开发的 Python 绑定,用于构建跨平台的图形用户界面(GUI)应用程序。它们在功能上非常相似,主要区别体现在授权方式、维护团队以及部分 API 设计上。
本文重点介绍通用 PySide 的环境配置、工具配置及使用方法,适用于在线、离线配置,兼容多个常用版本。
- PySide 环境配置 是进行 PySide 开发的第一步,虽然基础但至关重要。
- 在实际开发中,工具的使用 对开发效率影响较大。
- 与 Qt 官方安装包“开箱即用”的体验不同,PySide 相对较新,存在较多版本差异和 bug,因此本文将总结以下内容:
- 常用版本的环境搭建
- 工具配置与使用技巧
- 常见问题与 bug 的解决方案
- 主要版本:
- PySide2:基于 Qt 5(>=5.11);
- PySide6:基于 Qt 6,是当前推荐使用的版本;
1.1 PySide 能做什么?
- 图形用户界面开发:使用 Qt 提供的 QWidget 或 QML 模块构建桌面应用程序界面。
- 跨平台支持:支持 Windows、macOS、Linux 等主流操作系统。
- 多媒体和网络功能:内置模块支持音视频播放、网络通信(如 HTTP 请求、WebSocket)等功能。
- 数据可视化:利用 Qt Charts、QOpenGLWidget 等模块实现图表展示和 3D 渲染。
- 嵌入式系统开发:可用于开发嵌入式设备的 UI,如工业控制面板、车载系统等。
- 与 Web 技术集成:使用 Qt WebEngine 模块可以嵌入网页内容或开发混合型应用。
1.2 PySide 的优点
优点 | 描述 |
---|---|
🌐 跨平台 | 支持 Windows、Linux、macOS,甚至嵌入式系统。 |
📦 功能丰富 | 提供 GUI、网络、数据库、多线程、绘图等一整套模块。 |
🔧 官方支持 | PySide 是 Qt 官方提供的 Python 绑定,更新及时、文档完善。 |
🚀 性能较好 | 基于 C++ 的 Qt 引擎,性能优于 Tkinter 等纯 Python GUI 框架。 |
📐 支持 QML | 可以结合 QML 进行现代 UI 设计,适合动态界面。 |
1.3 PySide 的缺点
缺点 | 描述 |
---|---|
⚖️ 许可证复杂 | 商业用途需要购买 Qt 许可证;开源项目可用 LGPL 协议。 |
📦 包体积较大 | 打包发布时依赖较多,最终程序体积较大。 |
🧠 学习曲线陡峭 | Qt API 复杂,对新手有一定门槛,尤其是布局管理、信号槽机制等。 |
📱 移动端支持有限 | 虽然支持 Android/iOS,但不如原生开发或 Flutter/Kivy 成熟。 |
1.4 示例代码(简单窗口)
from PySide6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout # 导入必要的模块app = QApplication([]) # 创建一个QApplication实例,这是所有PySide6应用程序的基础
w = QWidget() # 创建主窗口部件(QWidget),它将作为应用程序的主窗口
label = QLabel("Hello, PySide6!", w) # 创建一个标签控件(QLabel),显示文本 "Hello, PySide6!"w.show() # 显示主窗口app.exec() # 进入应用程序的主循环,等待用户交互
2 环境准备
2.1 安装必要软件
- Python:从 Python 官方网站 下载并安装。
- PyCharm:从 PyCharm 官方网站 下载并安装。
- Qt(可选):从 Qt 官方下载页面 下载并安装。虽然可以在 Qt Creator 中开发 PyQt 项目,但 PyCharm 对 Python 语法的支持更好。
2.2 修改 pip 源
为避免默认源安装速度过慢,建议使用 阿里云 pip 镜像。按以下步骤操作,如果不存在则创建:
- Windows系统:
C:\Users\用户名\.pip\pip.conf
; - Linux系统:
~/.pip/pip.conf
; - 在
.pip
文件夹中创建一个pip.conf
文件,并添加以下内容:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/[install]
trusted-host=mirrors.aliyun.com
3 PySide2
3.1 环境要求
支持环境
环境 | 版本 |
---|---|
PySide2 | python2.7、3.5<=python<=3.10 |
系统 | win7+、linux、MacOS |
演示环境
环境 | 版本 |
---|---|
PySide2 | PySide2=5.15.2.1 |
python | V3.8.10 |
系统 | windows10 |
pycharm | pycharm-community-2024.3.5.exe |
3.2 配置PySide2
方法1: 命令行安装(在线)
- 使用
pip install pyside2
安装最新版本(网络状况差可能导致安装失败); - 使用
pip install pyside2==5.15.2.1
指定安装版本(网络状况差可能导致安装失败); - 使用
pip install PySide2 --index-url https://mirrors.aliyun.com/pypi/simple
指定临时安装源进行安装; - 使用
pip install https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-5.15.2.1-5.15.2-cp35.cp36.cp37.cp38.cp39.cp310-none-win_amd64.whl
指定下载地址进行安装;
方法2: 下载whl包安装(离线)
- 进入Index of /official_releases/QtForPython/pyside2或者PySide2 ·PyPI下载whl包到本地;
- 例如PySide2-5.15.2.1-5.15.2-cp35.cp36.cp37.cp38.cp39.cp310-none-win_amd64.whl;
- 然后使用
pip install ./PySide2-5.15.2.1-5.15.2-cp35.cp36.cp37.cp38.cp39.cp310-none-win_amd64.whl
命令进行安装。
方法3: 使用pycharm安装(在线)
-
打开pycharm,创建一个工程;
-
选择python软件包,搜索PySide2,如下所示,点击【安装】;
3.3 工具配置
pyside2或者pyside6<6.5的版本,内置工具不多,只有designer、lupdate、rcc、uic等几个;
如果需要用到其他工具,可以单独安装Qt安装包或者高版本的PySide6;
-
安装完成PySide2后,打开pycharm,【文件】【设置】【工具】【外部工具】;
-
点击+,如下所示配置
pyside2-designer
工具; -
配置完成后,点击【工具】【外部工具】就可以打开UI设计器。
-
使用
pyproject
文件管理工程是一个更加简便的方式,但是只有在PySide6.5以上版本才支持,这里通过自己编写脚本,可以通过pyproject文件对工程进行管理,简化部分操作; -
在工程顶级路径下创建一个project.py文件;
-
添加章节6脚本,运行脚本代码可自动执行重复操作,简化开发流程,避免出现基础错误。
4 PySide6
4.1 环境
支持环境
环境 | 版本 |
---|---|
PySide6 | 3.9<=python |
系统 | win10+、linux、MacOS |
支持win7系统 | python3.8 + PySide6.1.3 |
演示环境
环境 | 版本 |
---|---|
PySide6 | PySide6=6.8.3 |
python | V3.13.3 |
系统 | windows10 |
pycharm | pycharm-community-2024.3.5.exe |
4.2 配置PySide6
- 官方地址
安装方法1:使用命令行在线安装
-
使用
pip install PySide6
目录安装默认版本; -
使用
pip install pyside6==6.8.3
安装指定版本; -
使用
pip install PySide6 --index-url https://mirrors.aliyun.com/pypi/simple
指定安装源进行安装; -
使用
pip install https://download.qt.io/official_releases/QtForPython/pyside6-essentials/PySide6_Essentials-6.8.2.1-cp39-abi3-win_amd64.whl
指定下载地址进行安装; -
使用
pip install --index-url=https://download.qt.io/snapshots/ci/pyside/6.4/latest pyside6 --trusted-host download.qt.io
从指定服务器安装。
安装方法2: 使用pycharm安装
-
打开pycharm,创建一个工程;
-
选择python软件包,搜索PySide6,如下所示,点击【安装】;
安装方法3: 下载whl安装包,离线安装,对于离线环境或者网络不好pip安装失败的环境可用;
-
进入Index of /official_releases/QtForPython下载地址或者pypi下载地址;
-
一般下载pyside6-essentials/和shiboken6-generator/、shiboken6就可以;
-
分别进入pyside6-essentials/、shiboken6-generator/、shiboken6路径;
-
选择自己需要的版本、系统,例如
PySide6_Essentials-6.8.3-cp39-abi3-win_amd64.whl、shiboken6_generator-6.8.3-cp39-abi3-win_amd64.whl、shiboken6-6.9.0-cp39-abi3-win_amd64.whl
,下载到本地,主要3个包版本要相同; -
然后执行
pip install ./PySide6_Essentials-6.8.3-cp39-abi3-win_amd64.whl ./shiboken6_generator-6.8.3-cp39-abi3-win_amd64.whl ./shiboken6-6.9.0-cp39-abi3-win_amd64.whl
命令进行安装。
4.3 工具配置
-
打开【设置】【工具】【外部工具】,点击+;
-
添加
designer
,设置程序路径和工作目录如下所示; -
添加
pyside6-project
,用于构建pyside工程; -
更新翻译文件(ts)
-
打开翻译文件
pyside6-linguist
4.4 修改pyside6-project lupdate的bug
-
使用
pyside6-project lupdate
命令可以在 PySide6 中生成翻译使用的 ts 文件,但存在一些问题:- 无法将 ts 文件放在子文件夹下。
- 无法清除已经失效的文本。
-
这是因为
pyside6-project lupdate
中使用的是 ts 文件名,不包含路径,所以会在工程路径下执行,并且有几个 ts 文件就会执行几次。 -
解决办法:打开
.venv\Lib\site-packages\PySide6\scripts\project.py
文件,在def lupdate(self)
函数中修改为以下代码:def lupdate(self):for sub_project_file in self.project.sub_projects_files:Project(project_file=sub_project_file).lupdate()if not self.project.ts_files:print(f"{self.project.project_file.name}: No .ts file found.",file=sys.stderr)returnsource_files = self.project.python_files + self.project.ui_filesproject_dir = self.project.project_file.parentcmd_prefix = [LUPDATE_CMD] + [os.fspath(p.relative_to(project_dir)) for p in source_files]cmd_prefix.append("-ts")ts_files = []for ts_file in self.project.ts_files:if requires_rebuild(source_files, ts_file):ts_dir = ts_file.parentif not ts_dir.exists():ts_dir.mkdir(parents=True, exist_ok=True)ts_files.append(ts_file.resolve().as_posix())if ts_files:cmd = cmd_prefix;cmd.extend(ts_files)cmd.append("-no-obsolete") # 清除失效文本run_command(cmd, cwd=project_dir)
-
修改后,运行
pyside6-project.exe lupdate
命令就会将 ts 文件生成到指定路径中,并且只执行一次。(.venv) PS E:\Code\py\Test> pyside6-project.exe lupdate pyside6-lupdate main.py mainwindow.py TableWidget.py mainwindow.ui logwidget.ui control.ui -ts E:/Code/py/Test/Language/Test_zh_CN.ts E:/Code/py/Test/Language/Test_en_US.ts
5 工具使用
5.1 使用pyside6-project构建工程
-
需要pyside6.5以上版本支持,低版本可以通过自定义脚本支持(见后续章节);
-
创建一个
名称.pyproject
文件; -
按以下格式添加需要构建的文件名称,会批量将 ui 文件生成
ui_name.py
文件:{"files": ["main.py","widget.ui","widget1.ui"] }
-
运行
python project.py -o
命令,自动将所有文件加载到.pyproject
工程文件进行管理; -
鼠标点击【工具】【外部工具】【pyside6-project】,完成工程构建;
-
将ui、qrc文件生成为py文件;
-
将
.ts
翻译文件编译为.qm
文件;
-
-
注意:pyside6-project需要
tomlkit
库支持。
5.2 创建、打开ui文件
-
鼠标点击【工具】【外部工具】【pyside6-designer】,打开设计师窗口;
-
选择创建窗体类型,点击【创建】
-
创建完成后,按【Ctrl + S】将ui文件保存到工程文件夹中;
-
创建完成后在pycharm中就可以看见ui文件了,双击ui文件就可以使用设计器打开;
5.3 生成翻译文件
-
生成pyproject工程文件;
-
打开
.pyproject
工程文件,添加生成.ts
翻译文件的路径;{"files": ["main.py","res/res.qrc","res/language/en_US.ts","res/language/zh_CN.ts",] }
-
鼠标点击【工具】【外部工具】【lupdate】,自动将代码中需要翻译的文本输出到
.ts
文件,如果ts文件不存在则会自动创建,如果已存在则会更新; -
如果是小于PySide6.5版本,则使用自定义脚本命令
python project.py -lupdate
。
5.4 修改ts翻译文件
-
使用
lupdate
生成.ts
文件; -
鼠标选中
.ts
文件,右键【外部工具】【pyside6-linguist】,打开Qt语言家; -
在Qt语言家窗口中可将文本翻译为指定语言。
6 工程管理脚本
-
输入
python project.py -h
查看脚本使用方法。
"""
这个文件是用来搜索当前路径下所有py、ui、qrc、ts文件,并生成pyproject文件。
不再需要手动谢pyproject文件,只需要运行这个文件即可。
支持自动执行 Qt 用户界面编译器(uic)和 Qt 资源编译器(rcc);
支持自动执行 Qt 语言文件更新工具(lupdate);
"""
import fnmatch
import json
import os
import subprocess
from pathlib import Path # 更安全的路径处理
import importlib.util
import argparse
import sysdef list_files(directory='.', include_patterns=None, exclude_patterns=None, ignore_folders=None):"""列出指定目录下所有匹配指定模式的文件:param directory: 查询目录:param include_patterns: 搜索的文件,支持通配符:param exclude_patterns: 需要排除的文件,支持通配符:param ignore_folders: 需要忽略的文件夹:return: 匹配的文件列表,JSON 格式,输出为pyproject文件可用格式"""if include_patterns is None:include_patterns = {'*.py', '*.ui', '*.qrc', '*.ts'}if exclude_patterns is None:exclude_patterns = set()if ignore_folders is None:ignore_folders = set()files_list = []for root, dirs, files in os.walk(directory):# 过滤需要忽略的文件夹dirs[:] = [d for d in dirs if d not in ignore_folders]for file in files:# 检查文件是否匹配需要包含的通配符模式,并且不匹配需要排除的通配符模式if any(fnmatch.fnmatch(file, pattern) for pattern in include_patterns) and \not any(fnmatch.fnmatch(file, pattern) for pattern in exclude_patterns):# 计算相对路径relative_path = os.path.relpath(os.path.join(root, file), directory)relative_path = relative_path.replace('\\', '/')files_list.append(relative_path)# 返回 JSON 格式的文件列表return json.dumps({"files": files_list}, indent=4)def run_uic(project_name=None):"""执行 Qt 用户界面编译器(uic)的自动化流程▼ 典型工作流程:1. 定位 Qt 用户界面编译器(uic)2. 加载项目配置文件(JSON格式)3. 遍历配置文件中的 ui 文件路径4. 构建 uic 命令行参数5. 执行命令并处理执行结果,将ui文件编译为py文件"""project_file = Path(project_name).resolve()with open(project_file, 'r', encoding='utf-8') as f:config = json.load(f)# ▼ 配置有效性验证if 'files' not in config or not isinstance(config['files'], list):raise ValueError("配置文件必须包含 'files' 列表")ui_files = [Path(f).resolve() for f in config["files"] if f.endswith('.ui')]for ui_file in ui_files:filename = os.path.basename(ui_file)parent_dir = os.path.dirname(ui_file)out_file = os.path.join(parent_dir, 'ui_' + filename.replace('.ui', '.py'))if importlib.util.find_spec('PySide6') is not None: # 优先使用 PySide6, 如果找不到则使用 PySide2cmd_args = ['pyside6-uic', str(ui_file), '-o', out_file]elif importlib.util.find_spec('PySide2') is not None:cmd_args = ['pyside2-uic', str(ui_file), '-o', out_file]result = subprocess.run(cmd_args,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,check=True)print(f"执行命令: {result.args}")def run_rcc(project_name=None):"""执行 Qt 资源编译器(rcc)的自动化流程▼ 典型工作流程:1. 定位 Qt 资源编译器(rcc)2. 加载项目配置文件(JSON格式)3. 遍历配置文件中的 qrc 文件路径4. 构建 rcc 命令行参数5. 执行命令并处理执行结果,将qrc文件编译为py文件"""project_file = Path(project_name).resolve()with open(project_file, 'r', encoding='utf-8') as f:config = json.load(f)# ▼ 配置有效性验证if 'files' not in config or not isinstance(config['files'], list):raise ValueError("配置文件必须包含 'files' 列表")rc_files = [Path(f).resolve() for f in config["files"] if f.endswith('.qrc')]for rc_file in rc_files:filename = os.path.basename(rc_file)parent_dir = os.path.dirname(rc_file)out_file = os.path.join(parent_dir, 'rc_' + filename.replace('.qrc', '.py'))if importlib.util.find_spec('PySide6') is not None:cmd_args = ['pyside6-rcc', str(rc_file), '-o', out_file]elif importlib.util.find_spec('PySide2') is not None:cmd_args = ['pyside2-rcc', str(rc_file), '-o', out_file]result = subprocess.run(cmd_args,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,check=True)print(f"执行命令: {result.args}")def run_lupdate(project_name=None):"""执行 Qt 语言文件更新工具(lupdate)的自动化流程▼ 典型工作流程:1. 定位 Qt 语言更新工具(lupdate)2. 加载项目配置文件(JSON格式)3. 构建 lupdate 命令行参数4. 执行命令并处理执行结果▼ 配置文件要求:- 必须包含 'files' 键,值为文件路径列表- 示例配置:{"files": ["src/*.py","translations/zh_CN.ts","translations/en_US.ts"]}异常:ValueError: 当配置文件格式无效时抛出"""# 初始化路径对象(使用 pathlib 处理跨平台路径问题)# language: PySide6 语言更新工具的可执行路径# project_file: 项目配置文件路径(包含待翻译文件列表)# ts_files: 生成的翻译文件目标路径列表(中英文版本)if importlib.util.find_spec('PySide6') is not None:lupdate = Path('pyside6-lupdate.exe').resolve() # lupdate 工具路径,如果不存在,请手动修改路径# 构建基础命令参数(使用字符串显式转换保证兼容性)cmd_args = [str(lupdate), '-no-obsolete'] # -no-obsolete 选项用于排除已过时的翻译elif importlib.util.find_spec('PySide2') is not None:lupdate = Path('pyside2-lupdate.exe').resolve() # lupdate 工具路径,如果不存在,请手动修改路径# 构建基础命令参数(使用字符串显式转换保证兼容性)cmd_args = [str(lupdate), '-noobsolete']project_file = Path(project_name).resolve()try:# 读取并解析项目配置文件(JSON 格式)# 将配置中的文件列表添加到命令参数中with open(project_file, 'r', encoding='utf-8') as f:config = json.load(f)# ▼ 配置有效性验证if 'files' not in config or not isinstance(config['files'], list):raise ValueError("配置文件必须包含 'files' 列表")# 过滤掉以 .ts 为后缀的文件filtered_files = [file for file in config['files'] if not file.endswith('.ts')]cmd_args.extend(filtered_files) # 直接扩展参数列表# 从文件列表中筛选出以 .ts 结尾的文件路径# ts_files: 生成的翻译文件目标路径列表(中英文版本)ts_files = [Path(f).resolve() for f in config["files"] if f.endswith('.ts')]# ▼ 防止无翻译文件导致命令错误if not ts_files:print("警告:未发现.ts翻译文件")return# 添加翻译文件生成参数# -ts 参数后接转换后的字符串路径列表cmd_args.extend(['-ts', *map(str, ts_files)])# 执行外部命令并捕获输出# 使用 check=True 自动检查非零返回码# text=True 自动解码输出内容为字符串result = subprocess.run(cmd_args,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,check=True)print(f"执行命令: {' '.join(result.args)}")# ▼ 输出处理策略if result.stdout:print("输出日志:\n" + result.stdout)if result.stderr:print("错误信息:\n" + result.stderr)# ▼ 异常处理优先级调整except FileNotFoundError as e:print(f"关键文件缺失: {e.filename}")except json.JSONDecodeError as e:print(f"Json 解析错误: {project_file}: {e}")except subprocess.CalledProcessError as e:print(f"指令运行失败 (code {e.returncode}):\n{e.stderr}")except ValueError as e:print(f"配置验证失败: {e}")def find_pyproject_files(directory='.'):pyproject_files = []for root, dirs, files in os.walk(directory):for file in files:if fnmatch.fnmatch(file, '*.pyproject'):pyproject_files.append(os.path.join(root, file))return pyproject_filesif __name__ == '__main__':# 1. 创建解析器parser = argparse.ArgumentParser(description='工程管理')# 2. 添加参数parser.add_argument('-o', '--output', action='store_true', help='自动遍历当前路径下所有py、ui、qrc、ts文件,并生成pyproject文件')parser.add_argument('-b', '--build', action='store_true', help='构建项目,使用pyproject文件生成ui、qrc文件的py文件')parser.add_argument('-u', '--lupdate', action='store_true', help='执行 Qt 语言文件更新工具(lupdate)')parser.add_argument('-p', '--pyproject', type=str, help='指定pyproject文件路径,如果不指定则使用当前路径下的pyproject文件')# 3. 解析参数args = parser.parse_args()# 获取pyproject文件路径pyproject_file = args.pyprojectif not pyproject_file:pyprojects = find_pyproject_files()if pyprojects:pyproject_file = pyprojects[0]cmd_num = len(sys.argv) - 1if args.output or cmd_num == 0: # 使用-o 参数或者无参数时,执行输出# 列出当前路径下所有.py、.ui、.qrc、.ts文件,忽略.temp类型的文件和名为temp的文件夹ret = list_files(include_patterns={'*.py', '*.ui', '*.qrc', '*.ts'},exclude_patterns={'__init__.py', 'project.py', 'ui_*', 'rc_*'}, ignore_folders={'.venv'})if pyproject_file:with open(pyproject_file, 'w', encoding='utf-8') as project:project.write(ret)if args.build:if pyproject_file:# 可以选择不执行后面三个函数run_uic(pyproject_file) # 执行 Qt 用户界面编译器, 将ui文件编译为py文件run_rcc(pyproject_file) # 执行 Qt 资源编译器, 将qrc文件编译为py文件if args.lupdate:run_lupdate(pyproject_file) # 执行 Qt 语言文件更新工具(lupdate)
7 相关地址
- Qt for Python地址
- 模块 API - Qt for Python
- PySide下载地址
- pyside6下载地址1
- pyside6下载地址2
- PySide6包依赖
- PyQt6地址
- PyQt6文档
- PyQt6下载地址