-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.py
More file actions
146 lines (129 loc) · 4.23 KB
/
build.py
File metadata and controls
146 lines (129 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
打包脚本
作者:aidaox
创建日期:2025-01-17
"""
import PyInstaller.__main__
import os
import sys
from pathlib import Path
def find_python_dll():
"""查找Python DLL文件"""
possible_paths = [
os.path.dirname(sys.executable), # 当前Python环境
os.path.dirname(os.path.dirname(sys.executable)), # 虚拟环境的父目录
r"C:\ProgramData\miniconda3", # Miniconda安装目录
r"C:\Python310", # 标准Python安装目录
]
for path in possible_paths:
dll_path = os.path.join(path, 'python310.dll')
if os.path.exists(dll_path):
return dll_path, path
raise FileNotFoundError("Cannot find python310.dll")
def build_exe():
"""打包为exe可执行文件"""
# 获取当前目录
current_dir = Path(__file__).parent
# 查找Python DLL
python_dll, python_dir = find_python_dll()
# 定义资源文件
resources = [
# 配置文件
('config/config.yaml', 'config'),
# 图标文件
('src/resources/icons/icon.png', 'src/resources/icons'),
# 样式文件
('src/resources/styles/*.qss', 'src/resources/styles'),
]
# 准备打包参数
args = [
'src/main.py', # 主程序入口
'--name=heicto', # 程序名称
'--windowed', # 使用GUI模式
'--onefile', # 生成单个exe文件
'--icon=src/resources/icons/icon.png', # 程序图标
'--add-data=src/resources/icons;resources/icons',
'--add-data=src/resources/styles;resources/styles', # 添加样式文件
'--add-data=config/config.yaml;config', # 添加配置文件
'--noconfirm', # 不确认覆盖
'--clean', # 清理临时文件
f'--distpath={current_dir}/dist', # 输出目录
f'--workpath={current_dir}/build', # 工作目录
f'--specpath={current_dir}', # spec文件目录
f'--paths={python_dir}', # Python路径
'--collect-all=PIL', # 收集所有PIL相关文件
'--collect-all=PyQt6', # 收集所有PyQt6相关文件
'--collect-all=reportlab', # 收集所有reportlab相关文件
'--collect-all=pillow_heif', # 收集所有pillow_heif相关文件
'--collect-all=loguru', # 收集所有loguru相关文件
f'--add-binary={python_dll};.', # 添加Python DLL
]
# 添加数据文件
for src, dst in resources:
args.append(f'--add-data={src};{dst}')
# 添加需要的包
hidden_imports = [
'PIL',
'PIL._webp',
'PyQt6.QtCore',
'PyQt6.QtGui',
'PyQt6.QtWidgets',
'PyQt6.QtPrintSupport',
'loguru',
'yaml',
'pkg_resources.py2_warn',
'email',
'reportlab',
'reportlab.pdfgen',
'reportlab.pdfbase',
'reportlab.pdfbase.ttfonts',
'reportlab.lib.pagesizes',
'reportlab.lib.units',
'reportlab.lib.utils'
]
for imp in hidden_imports:
args.append(f'--hidden-import={imp}')
# 排除不需要的模块
exclude_modules = [
# PyQt6相关
'PyQt6.QtBluetooth',
'PyQt6.QtDBus',
'PyQt6.QtDesigner',
'PyQt6.QtHelp',
'PyQt6.QtLocation',
'PyQt6.QtMultimedia',
'PyQt6.QtMultimediaWidgets',
'PyQt6.QtNetwork',
'PyQt6.QtNfc',
'PyQt6.QtOpenGL',
'PyQt6.QtPositioning',
'PyQt6.QtQml',
'PyQt6.QtQuick',
'PyQt6.QtSensors',
'PyQt6.QtSerialPort',
'PyQt6.QtSql',
'PyQt6.QtSvg',
'PyQt6.QtTest',
'PyQt6.QtWebChannel',
'PyQt6.QtWebEngine',
'PyQt6.QtWebEngineCore',
'PyQt6.QtWebEngineWidgets',
'PyQt6.QtWebSockets',
'PyQt6.QtXml',
# 其他确定不需要的模块
'tkinter',
'curses',
'unittest',
'pydoc',
'xmlrpc'
]
for module in exclude_modules:
args.append(f'--exclude-module={module}')
print(f"Using Python DLL from: {python_dll}")
print(f"Python directory: {python_dir}")
# 执行打包
PyInstaller.__main__.run(args)
if __name__ == '__main__':
build_exe()