import os import subprocess import sys import shutil import platform MAIN_FILE = "main_nicegui.py" def copy_resources(): """ 将资源文件从项目根目录复制到 dist 文件夹中, 以便用户可以直接在 exe 旁边修改这些文件。 """ current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(current_dir) dist_dir = os.path.join(current_dir, "dist") print(f"\n--- 正在复制外部资源到 {dist_dir} ---") if not os.path.exists(dist_dir): print("错误: dist 文件夹不存在,请先运行打包。") return # 这里的列表是【给用户看/改的】,不用把 ui/assets 放这里,除非你希望用户改CSS resources_to_copy = [ ("config.toml", ""), ("fonts", "fonts"), ("data", "data"), ("templates", "templates"), ("public", "public"), # ui/assets 通常不需要用户改,所以这里可以不复制到外部,只打在包里即可 # 但如果你希望用户能自定义 logo,也可以复制出来 ] for src_name, dest_name in resources_to_copy: src_path = os.path.join(project_root, src_name) dest_path = os.path.join(dist_dir, dest_name) try: if os.path.isfile(src_path): shutil.copy2(src_path, dest_path) print(f"✅ 已复制文件: {src_name}") elif os.path.isdir(src_path): shutil.copytree(src_path, dest_path, dirs_exist_ok=True) print(f"✅ 已复制目录: {src_name}") else: print(f"⚠️ 警告: 源文件不存在,跳过: {src_path}") except Exception as e: print(f"❌ 复制失败 {src_name}: {e}") def build_exe(): """使用 PyInstaller 打包""" # 1. 确定当前系统的分隔符 (Windows用';', Linux/Mac用':') sep = ';' if platform.system() == "Windows" else ':' # 2. 定义内部资源 (打入 exe 肚子里的) # 格式: "源路径{sep}目标路径" resource_paths = [ f"../config.toml{sep}.", # 默认配置 f"../fonts{sep}fonts", # 字体 (程序可能需要内部路径) f"../templates{sep}templates", # 模板 f"../ui/assets{sep}ui/assets", # <--- 关键修复:添加 UI 静态资源 # public 和 data 如果体积太大且只在运行时读取,可以不打入包内,只保留外部复制 ] try: command = [ sys.executable, "-m", "PyInstaller", "--onefile", "--windowed", # 建议:先注释掉这行,打包出来先看黑框有没有报错,没问题了再开启 "--name=尚城幼儿园幼儿学期发展报告", "--clean", # 清理缓存,避免旧文件干扰 "--distpath=./dist", # 明确输出目录 "--workpath=./build", "--icon=../public/icon.ico", # 确保你真有这个图标,否则会报错 "../" + MAIN_FILE ] # 添加 --add-data 参数 for res in resource_paths: command.append(f"--add-data={res}") # 添加 hidden-import (NiceGUI 常见缺失) command.extend(["--hidden-import=nicegui", "--hidden-import=uvicorn"]) print("--- 开始打包 (PyInstaller) ---") subprocess.run(command, check=True, cwd=os.path.dirname(os.path.abspath(__file__))) print("\n--- PyInstaller 打包完成!---") copy_resources() print(f"\n🎉 全部完成!请查看 'dist' 文件夹。") except subprocess.CalledProcessError as e: print(f"\n❌ 打包失败: {e}") except Exception as e: print(f"\n❌ 发生错误: {e}") if __name__ == "__main__": build_exe()