PyInstaller加--noconsole打包pygame的exe运行后报脚本执行错误
问题根因
使用--noconsole参数打包的PyInstaller程序无控制台输出通道,所有未被捕获的运行时异常都会直接弹出「Failed to execute script」提示;控制台模式下异常直接打印到后台窗口,不会触发弹窗。
从现有代码看,退出时报错是两个代码逻辑错误导致的:
- 主函数
main()的while循环结束后,存在多余的递归调用main()逻辑,触发关闭事件将objects.run设为False、跳出循环后,会重新进入主函数逻辑,此时pygame资源已经被释放,调用渲染、事件接口直接抛异常 - 事件分支中直接调用
exit()退出,该方法是交互式解释器内置的退出方法,在无控制台的打包exe中运行会触发进程退出异常,且直接在事件循环中调用pygame.quit()会导致后续循环内的渲染逻辑访问已销毁的窗口对象抛错
修复方案
- 代码头部新增标准库导入:
import sys - 修正主函数退出逻辑,删除循环外多余的递归调用,将资源释放、退出操作统一放到主循环结束后执行,修改后的
main()函数参考:def main(): clock = pygame.time.Clock() tiles = generate_world() while objects.run: clock.tick(FPS) objects.to_draw = [] for event in pygame.event.get(): if event.type == pygame.QUIT: objects.run = False # 仅标记退出状态,不在事件循环内直接销毁资源、退出进程 for x in range(0, WORLD_WIDTH): for y in range(0, WORLD_HEIGHT): objects.to_draw.append(tiles[x][y]) handle_keys() pymc.draw_window(WIN, objects.to_draw, fill=(0, 150, 255)) # 主循环正常结束后统一释放资源、退出 pygame.quit() sys.exit() if __name__ == "__main__": main() - 清理之前打包生成的
build、dist文件夹和同名.spec缓存文件,重新执行打包命令:pyinstaller --noconsole --clean 2d_minecraft.py
排查兜底方案
如果修改后仍有弹窗,可暂时去掉--noconsole参数打包运行,触发关闭操作时查看控制台打印的具体异常栈,对应排查是否存在其他未释放的资源、或调用已销毁pygame对象的逻辑即可。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

