双击exe没反应需先用--console和--debug=all参数运行以查看报错;GUI程序要确保入口在if name == '__main__':内且调用mainloop()或exec();资源路径须用resource_path()函数适配,多进程必须加freeze_support()。

双击exe没反应?先弹出控制台看报错
绝大多数“无法启动”其实不是真卡死,而是程序秒崩后控制台一闪而过。直接双击看不到任何线索,必须强制让它把错误打出来。
用这个命令重打包:pyinstaller --debug=all --console your_script.py。注意两点:一是--console会强制弹窗,二是--debug=all比--debug=imports更狠,能暴露importlib.metadata、动态插件加载这类隐式导入失败。
- 如果弹窗后立刻报
ModuleNotFoundError,说明缺依赖,记下模块名,后面加--hidden-import - 如果卡在某行路径拼接上,比如
FileNotFoundError: [Errno 2] No such file or directory: 'config.yaml',那就是资源路径没适配 - 如果压根不弹窗,但任务管理器里进程闪一下就消失,大概率是
multiprocessing没加freeze_support()
tkinter/PyQt窗口一闪就消失?检查入口和打包参数
GUI程序打包后黑屏或闪退,90%出在两个地方:入口函数没走完,或者--windowed误用导致控制台被藏掉却没捕获异常。
确保主逻辑包在if __name__ == '__main__':里,且最后一行是root.mainloop()(tkinter)或app.exec()(PyQt)。别在mainloop()前面写可能抛异常的代码——它一崩,窗口就关。
立即学习“Python免费学习笔记(深入)”;
- 调试阶段别用
--windowed,先用--console跑通,确认无报错再切回--windowed - PyQt5/6用户注意:
QApplication必须在if __name__ == '__main__':内创建,否则打包后sys.argv为空,初始化失败 - tkinter图标加载失败?别用
iconbitmap('icon.ico')硬路径,改用root.iconbitmap(resource_path('icon.ico'))
图片/配置文件打不开?别信相对路径
开发时open('data/config.json')能跑,打包后必跪。因为exe解压到临时目录运行,__file__和os.getcwd()都指向错地方。
统一用这个函数取资源路径:resource_path():
import sys
import os
<p>def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath('.'), relative_path)- 所有资源——图片、字体、JSON、SQL模板——都得套这层函数,比如
Image.open(resource_path('img/logo.png')) - 用
--add-data把资源打进exe:pyinstaller --add-data "data;data" --add-data "images;images" your_script.py(分号前是源路径,后是exe内虚拟路径) - PyInstaller 6.0+对
data目录自动处理更严格,如果data里有子目录,--add-data必须逐级指定,不能只写"data;."
多进程程序打包后崩溃?Windows下必须加freeze_support
Windows的multiprocessing机制和打包工具天生打架:子进程启动时找不到父进程的Python解释器入口,直接退出。
唯一解法:在if __name__ == '__main__':最开头加multiprocessing.freeze_support(),位置不能错。
- 示例结构:
import multiprocessing <p>if <strong>name</strong> == '<strong>main</strong>': multiprocessing.freeze_support() # 必须第一行! p = multiprocessing.Process(target=worker) p.start() p.join()
- 如果用了
concurrent.futures.ProcessPoolExecutor,同样要加,原理一样 - 这个函数在Linux/macOS下无效但安全,所以不用条件判断,直接写就行
- PyInstaller 5.0+虽尝试自动注入,但不保证100%生效,手动加才是稳的
真正麻烦的从来不是打包命令本身,而是那些只在打包后才浮出水面的路径假设、隐式依赖和平台特异性行为。每次改完代码,别急着双击exe,先跑一遍带--console的版本——那几秒弹窗里的报错信息,比猜三天都管用。


















