使用pyinstaller打包Pygame游戏生成可执行文件后运行报TypeError错误
问题原因
你使用相对路径加载本地图片、音频、字体资源,PyInstaller单文件模式运行时会将所有打包内容释放到系统临时目录(通过sys._MEIPASS变量指向该路径),此时原相对路径无法定位资源,且PyInstaller默认将非代码文件封装为BytesIO对象,pygame的资源加载接口无法直接处理该类型对象,因此抛出类型错误。
解决方案
步骤1:修改代码适配打包环境
首先在代码顶部引入sys和os模块,新增资源路径解析函数:
import sys import os import pygame as pg import random import time import pygame.time from pygame import mixer def resource_path(relative_path): """ 自动适配开发环境和PyInstaller打包环境,返回资源的绝对路径 """ try: # PyInstaller运行时的临时目录路径 base_path = sys._MEIPASS except AttributeError: # 本地开发环境下取脚本所在目录 base_path = os.path.abspath(".") return os.path.join(base_path, relative_path)
然后将所有资源加载的相对路径替换为resource_path(原相对路径),示例修改如下:
# 修改前 icon = pg.image.load('001-ufo.png') # 修改后 icon = pg.image.load(resource_path('001-ufo.png')) # 其他所有资源加载处均做同样修改,例如: mixer.music.load(resource_path('Tetris.mp3')) font = pg.font.Font(resource_path('freesansbold.ttf'), 34) self.image = pg.image.load(resource_path('bullet.png')) self.fire_sound = mixer.Sound(resource_path('rocket_sound.wav')) self.explosion_sound = mixer.Sound(resource_path('explosion.wav')) self.image = pg.image.load(resource_path('player.png'))
步骤2:调整PyInstaller打包命令
打包时需要通过--add-data参数将所有资源文件一起打包,不同系统的参数分隔符不同:
Windows系统打包命令
pyinstaller --onefile --add-data "001-ufo.png;." --add-data "Tetris.mp3;." --add-data "bullet.png;." --add-data "rocket_sound.wav;." --add-data "explosion.wav;." --add-data "player.png;." --add-data "freesansbold.ttf;." main.py
macOS/Linux系统打包命令
pyinstaller --onefile --add-data "001-ufo.png:." --add-data "Tetris.mp3:." --add-data "bullet.png:." --add-data "rocket_sound.wav:." --add-data "explosion.wav:." --add-data "player.png:." --add-data "freesansbold.ttf:." main.py
打包验证
打包完成后,生成的独立可执行文件存放在项目根目录的dist文件夹内,无需附带资源文件即可直接运行。
内容的提问来源于stack exchange,提问作者Kshitijthegreat
相关产品推荐
相关产品推荐

