代码写完了,测试跑通了,怎么给用户?
PyInstaller打包、spec配置、资源处理、权限问题——一个不少
一、部署需求
1.1 目标环境
-
操作系统:Windows 10/11(64位)
-
用户:生产一线操作人员(非技术人员)
-
部署方式:独立exe,双击即用
1.2 部署要求
| 要求 | 说明 |
|---|---|
| 无需安装Python | 用户不需要装任何环境 |
| 一键运行 | 双击exe直接启动 |
| 全部打包 | 所有依赖打进一个文件 |
| 配置持久化 | 配置保存在用户目录 |
二、PyInstaller基础
2.1 安装
bash
pip install pyinstaller
2.2 基础命令
bash
pyinstaller --onefile --windowed --name="毛刺检测系统" main.py
2.3 参数说明
| 参数 | 作用 |
|---|---|
--onefile | 单exe文件 |
--windowed | 不显示控制台窗口 |
--name | 生成的exe文件名 |
三、spec文件配置(关键)
3.1 生成spec模板
bash
pyinstaller --onefile --windowed --name="毛刺检测系统" main.py --specpath=./
3.2 完整spec文件
python
import sys
from PyInstaller.utils.hooks import collect_all
block_cipher = None
# 收集所有依赖
datas = []
hiddenimports = []
# OpenCV
opencv_datas, opencv_binaries, opencv_hiddenimports = collect_all('cv2')
datas.extend(opencv_datas)
hiddenimports.extend(opencv_hiddenimports)
# numpy
numpy_datas, numpy_binaries, numpy_hiddenimports = collect_all('numpy')
datas.extend(numpy_datas)
hiddenimports.extend(numpy_hiddenimports)
# PyQt6
pyqt6_datas, pyqt6_binaries, pyqt6_hiddenimports = collect_all('PyQt6')
datas.extend(pyqt6_datas)
hiddenimports.extend(pyqt6_hiddenimports)
# 隐式导入模块
hiddenimports.extend([
'uiautomation',
'openpyxl',
'pickle'
])
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='毛刺检测系统',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True, # 用UPX压缩
upx_exclude=[],
runtime_tmpdir=None,
console=False, # 不显示控制台
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='app.ico' # 如果有图标
)
3.3 spec关键配置
| 配置项 | 作用 |
|---|---|
collect_all('cv2') | 自动收集OpenCV所有依赖 |
collect_all('numpy') | 自动收集numpy所有依赖 |
collect_all('PyQt6') | 自动收集PyQt6所有依赖 |
hiddenimports | 手动添加隐式导入的模块 |
upx=True | 用UPX压缩,减小体积 |
console=False | 不显示命令行窗口 |
四、资源文件处理
4.1 运行时路径
python
def get_resource_path(relative_path):
"""获取资源文件路径(开发环境 vs 打包后)"""
try:
# PyInstaller打包后的临时目录
base_path = sys._MEIPASS
except Exception:
# 开发环境
base_path = os.path.abspath('.')
return os.path.join(base_path, relative_path)
4.2 添加资源到spec
python
datas = [
('logs/', 'logs/'), # 日志目录
('results/', 'results/'), # 结果目录
('25KAL0044-002复测/', '25KAL0044-002复测/'), # 示例图像
]
五、执行打包
bash
pyinstaller 毛刺检测.spec
打包输出
text
dist/ └── 毛刺检测系统.exe # 可执行文件
六、打包后测试
6.1 功能测试清单
-
双击启动
-
选择目录加载图像
-
单张检测
-
批量检测
-
重新检测
-
发送定位(F10)
-
保存/加载结果
6.2 兼容性测试
| 测试环境 | 结果 |
|---|---|
| Windows 10(有Python) | ✅ |
| Windows 10(无Python) | ✅ |
| Windows 11(无Python) | ✅ |
七、版本管理
7.1 版本号
python
__version__ = '1.0.0'
7.2 更新流程
-
改版本号
-
重新打包
-
替换旧exe
-
配置自动继承(QSettings存在用户目录)
八、常见问题与解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 启动提示缺少DLL | OpenCV依赖未打包 | spec中添加collect_all('cv2') |
| uiautomation找不到控件 | 权限不足 | 以管理员身份运行 |
| 读取图像失败 | 资源路径错误 | 用get_resource_path() |
| exe体积过大 | 打包了不必要的库 | 用excludes=[]排除 |
九、部署文档(给用户)
快速上手
-
解压压缩包
-
双击
毛刺检测系统.exe -
点击"选择目录"加载图像
-
点击"开始检测"
注意事项
-
管理员身份运行(uiautomation需要)
-
首次使用需配置外部控件参数
-
图像文件名建议包含数字序号(便于坐标匹配)
十、踩坑记录
-
collect_all要导入:from PyInstaller.utils.hooks import collect_all -
管理员权限:uiautomation操作外部进程必须管理员运行
-
路径判断:
sys._MEIPASS只在打包后存在,要用try-except兜底 -
UPX压缩:有UPX就开,没UPX也正常打包,不影响功能
-
控制台窗口:
console=False不显示,但调试时建议True看日志
系列文章总结
圆孔毛刺检测系统系列到此完结:
-
项目概述与整体架构
-
图像处理核心算法——圆孔定位
-
RANSAC圆拟合算法深度解析
-
自适应缺陷检测算法设计
-
UI自动化与外部控制集成
-
PyQt6界面开发实战
-
多线程批量处理机制
-
数据存储与结果管理
-
系统测试与性能优化
-
部署与打包方案(本文)
如果对部署打包有不同思路,评论区聊。
520

被折叠的 条评论
为什么被折叠?



