使用 PyQt5 进行 GUI 开发,并通过 PyInstaller 打包为可执行文件
一、PyQt5 GUI 开发示例
1. 安装 PyQt5
首先,安装 PyQt5 :
1 | bash |
2. 创建简单的 PyQt5 界面(这一部分建议chatgpt来写)
假设我们开发一个简单的工资计算器,用户输入基本工资、绩效奖金后,点击按钮计算总工资。
(1)使用 Qt Designer 设计 UI
PyQt5 提供了一个可视化 UI 设计工具 Qt Designer,可以使用以下命令打开它(Windows):
1 | bash |
在 Qt Designer 里:
- 创建一个
QWidget窗口。 - 添加
QLineEdit用于输入基本工资和绩效奖金。 - 添加
QPushButton按钮用于计算工资。 - 添加
QLabel显示计算结果。 - 保存 UI 文件,如
salary_calculator.ui。
(2)转换 .ui 文件为 Python 代码
使用 pyuic5 将 UI 文件转换为 Python 代码:
1 | bash |
(3)编写主逻辑代码
创建 main.py,并编写工资计算逻辑:
1 | python |
二、使用 PyInstaller 进行打包
1. 安装 PyInstaller
1 | bash |
2. 生成可执行文件
在终端运行以下命令,将 main.py 打包成 Windows 可执行文件:
1 | bash |
打包成功后,Windows 用户会在 dist 目录下找到 main.exe,macOS 用户会得到 .app 应用包。
注意:打包要在目标平台进行:Windows 上打包 Windows 应用,macOS 上打包 macOS 应用。
三、在win7上运行
如果在win10上打包,因为pyinstaller默认会打包win10的api,故在win7上运行时会报错:计算机丢失 api-ms-win-core-path-l1-1-0.dll等。
所以必须使用pyinstaller在win7上打包,打包后的exe才能在win7上运行。
win10机器安装win7虚拟机并完成pyinstaller打包步骤:
- 安装vmware(17.0.2之后版本个人使用免费),假如win10在1909版本之前的本系统,安装vmware前需要同时处理Hyper-V和Virtualization-Based Security的兼容性问题(可使用下文脚本)。
- 安装win7(MSDN,i tell you)
- 安装python3.8.10(最后支持win7的python)
+ 可能报错缺少service pack,安装KB976932 和 KB2533623 补丁
+ 参考:教程 - 假如要用cryptography,请使用38.0.4版本
三、解决单一实例限制
用户多次点击 PyInstaller 打包生成的 .exe 文件时,程序会启动多个实例(多开),而你希望无论点击多少次,都只运行一个应用界面(单一实例)。这在 GUI 应用程序中是常见需求,称为单一实例限制。
问题分析
PyInstaller 打包的 .exe 行为:每次点击 .exe 文件,PyInstaller 默认会启动一个新的进程,导致多个独立的应用实例运行。
PyQt5 的特点:PyQt5 本身不会自动限制单一实例,需要手动实现进程间通信(IPC)或锁机制来确保只有一个实例运行。
你的代码:当前的 main.py 没有实现单一实例检查,因此每次点击 .exe 都会启动新的进程和窗口。
解决办法:使用本地 socket 进行 IPC(更灵活)
通过本地 socket 实现进程间通信(IPC)。当新实例启动时,它会尝试连接到一个已知的 socket 端口。如果连接成功,说明已有实例运行,新实例可以发送消息激活已有窗口并退出
以下是一个基于 QLocalSocket 和 QLocalServer 的实现:
1 | import sys |
说明
- QLocalServer 和 QLocalSocket:PyQt5 提供的跨平台 IPC 机制,用于进程间通信。
- 工作原理:
- 第一个实例启动时,创建并监听一个本地 socket(PensionAppInstance)。
- 新实例启动时,尝试连接到该 socket。如果连接成功,说明已有实例运行,新实例发送“activate”消息并退出。
- 已有实例收到消息后,通过 raise_() 和 activateWindow() 将窗口置顶并激活。
- 优势:不仅防止多开,还能激活已有窗口,提升用户体验。
- 清理:在窗口关闭时通过 closeEvent 清理服务器,确保下次启动时不会冲突。
- PyInstaller 兼容性:此方法适用于 PyInstaller 打包的程序,无需额外依赖。
PS
关闭 Virtualization-Based Security:以下代码写成bat文件,管理员权限运行即可
1 | @echo off |
