# -*- mode: python ; coding: utf-8 -*- import os import sys SPEC_DIR = ( os.path.abspath(os.path.dirname(__file__)) if "__file__" in globals() else os.getcwd() ) if SPEC_DIR not in sys.path: sys.path.insert(0, SPEC_DIR) from app_version import APP_NAME, APP_VERSION from PyInstaller.utils.win32.versioninfo import ( VSVersionInfo, FixedFileInfo, StringFileInfo, StringTable, StringStruct, VarFileInfo, VarStruct, ) def build_windows_version(version_text): parts = [int(part) for part in version_text.split('.') if part.strip()] parts = (parts + [0, 0, 0, 0])[:4] return tuple(parts) windows_version = build_windows_version(APP_VERSION) windows_version_text = '.'.join(str(part) for part in windows_version) version_info = VSVersionInfo( ffi=FixedFileInfo( filevers=windows_version, prodvers=windows_version, mask=0x3F, flags=0x0, OS=0x40004, fileType=0x1, subtype=0x0, date=(0, 0), ), kids=[ StringFileInfo( [ StringTable( '080404B0', [ StringStruct('CompanyName', 'Moka'), StringStruct('FileDescription', APP_NAME), StringStruct('FileVersion', windows_version_text), StringStruct('InternalName', 'pqAutomationApp'), StringStruct('OriginalFilename', 'pqAutomationApp.exe'), StringStruct('ProductName', APP_NAME), StringStruct('ProductVersion', windows_version_text), ], ) ] ), VarFileInfo([VarStruct('Translation', [2052, 1200])]), ], ) a = Analysis( ['pqAutomationApp.py'], pathex=[], binaries=[], datas=[('assets', 'assets'), ('UniTAP', 'UniTAP')], hiddenimports=[ # app 包的子模块在主文件里是静态 import 的,但惰性调用 / 属性绑定 # 场景较多,显式列出可避免 PyInstaller 漏打包。 'app', 'app.config_io', 'app.data_range_converter', 'app.resources', 'app.device', 'app.device.connection', 'app.pq', 'app.pq.pq_config', 'app.pq.pq_result', 'app.plots', 'app.plots.plot_accuracy', 'app.plots.plot_cct', 'app.plots.plot_contrast', 'app.plots.plot_eotf', 'app.plots.plot_gamma', 'app.plots.plot_gamut', 'app.runner', 'app.runner.test_runner', 'app.tests', 'app.tests.color_accuracy', 'app.tests.eotf', 'app.tests.gamma', 'app.tests.gamut', 'app.tests.local_dimming', 'app.views', 'app.views.chart_frame', 'app.views.collapsing_frame', 'app.views.panel_manager', 'app.views.pq_debug_panel', 'app.views.pq_log_gui', 'app.views.panels', 'app.views.panels.cct_panel', 'app.views.panels.custom_template_panel', 'app.views.panels.main_layout', 'app.views.panels.side_panels', 'drivers', 'drivers.baseSerail', 'drivers.caSerail', 'drivers.tvSerail', 'drivers.UCD323_Enum', 'drivers.UCD323_Function', 'drivers.ucd_helpers', ], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[ 'PyQt5', 'PyQt6', 'PySide2', 'PySide6', 'cv2', 'imageio', 'imageio_ffmpeg', 'IPython', 'jedi', ], noarchive=False, # numpy 在运行时依赖部分 docstring,optimize=2 会移除 docstring 导致启动报错。 optimize=0, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='pqAutomationApp', debug=False, bootloader_ignore_signals=False, strip=False, # 关闭 UPX:通常可减少启动时解压与杀软扫描开销,提升冷启动体感。 upx=False, console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, contents_directory='internal', version=version_info, icon=os.path.join(SPEC_DIR, 'assets', 'pq.ico'), ) coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=False, upx_exclude=[], name='pqAutomationApp', )