""" 打包脚本 - 使用 PyInstaller 打包 PCM Viewer 使用方法: python build.py # 打包为单文件(推荐) python build.py --onedir # 打包为文件夹 """ import os import sys import shutil import subprocess def get_resource_path(relative_path): """获取资源文件的绝对路径(支持打包后的单文件模式)""" try: # PyInstaller 创建的临时文件夹 base_path = sys._MEIPASS except Exception: # 开发环境:使用脚本所在目录 base_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(base_path, relative_path) def main(): # 检查是否安装了 PyInstaller try: import PyInstaller except ImportError: print("错误:未安装 PyInstaller") print("请运行: pip install pyinstaller") sys.exit(1) # 解析命令行参数 onedir = "--onedir" in sys.argv # 清理之前的构建 if os.path.exists("build"): shutil.rmtree("build") if os.path.exists("dist"): shutil.rmtree("dist") if os.path.exists("PCM_Viewer.spec"): os.remove("PCM_Viewer.spec") # 构建 PyInstaller 命令(已优化启动速度) cmd = [ "pyinstaller", "--name=PCM_Viewer", "--windowed", # 不显示控制台窗口 "--onefile" if not onedir else "--onedir", # ========== 启动速度优化 ========== "--noupx", # 不使用 UPX 压缩(UPX 会增加启动时间) "--optimize=2", # Python 字节码优化级别(0-2,2 最高) # 排除不需要的大型模块(减少打包体积和启动时间) "--exclude-module=matplotlib", "--exclude-module=numpy", "--exclude-module=pandas", "--exclude-module=scipy", "--exclude-module=PIL", "--exclude-module=tkinter", # 隐藏导入(延迟导入的模块) "--hidden-import=PyQt6.QtWebEngineWidgets", "--hidden-import=influxdb_client", "--hidden-import=influxdb_client.client", "--hidden-import=influxdb_client.client.write_api", "--hidden-import=influxdb_client.client.query_api", "--hidden-import=influxdb_wrapper", # 只收集必要的 PyQt6 模块(不收集全部,减少体积) "--collect-all=PyQt6.QtWebEngineWidgets", # WebEngine 需要完整收集 "main.py" ] print("开始打包...") print(f"模式: {'单文件' if not onedir else '文件夹'}") print(f"命令: {' '.join(cmd)}") print() # 执行打包 result = subprocess.run(cmd, check=False) if result.returncode == 0: print("\n打包成功!") if not onedir: print("单文件位置: dist/PCM_Viewer.exe") print("\n注意:") print("1. 首次运行会在 exe 同目录创建配置文件") print("2. dashboard.json 和 influx_settings.json 会保存在 exe 同目录") else: print("文件夹位置: dist/PCM_Viewer/") print("可执行文件: dist/PCM_Viewer/PCM_Viewer.exe") else: print("\n打包失败!") sys.exit(1) if __name__ == "__main__": main()