PyInstaller打包实践:资源缺失报错解决
创作时间:
作者:
@小白创作中心
PyInstaller打包实践:资源缺失报错解决
引用
CSDN
1.
https://blog.csdn.net/2301_79442295/article/details/144324316
在使用PyInstaller打包Python项目时,经常会遇到资源文件缺失的问题。本文通过一个具体的Flappy Bird游戏项目为例,详细介绍了如何通过修改代码来解决打包后资源文件路径问题。
准备
首先需要安装PyInstaller:
pip install pyinstaller
打包命令如下:
pyinstaller --onefile --windowed --icon=flappy.ico --add-data "assets/sprites;assets/sprites" --add-data "assets/audio;assets/audio" main.py
参数说明:
--onefile:将所有文件打包成一个单独的 .exe 文件。--windowed:防止显示控制台窗口。这对于图形界面程序(如使用 Pygame 的游戏)非常有用,可以避免控制台窗口弹出。--icon=flappy.ico:指定自定义的软件图标(flappy.ico)用于 .exe 文件。--add-data "assets/sprites;assets/sprites":将 assets/sprites 目录中的文件添加到打包文件中,并保留目录结构。--add-data "assets/audio;assets/audio":将 assets/audio 目录中的文件添加到打包文件中,并保留目录结构。main.py:指定你的主 Python 脚本路径。
修改代码
在原项目中,项目结构如下:
src:主要是代码文件assets:主要是项目的资源文件(包括图片与声音文件)main.py:程序入口
使用PyInstaller打包后找不到资源文件是因为当 PyInstaller 打包时,资源文件的路径会被修改。你需要使用 sys._MEIPASS 来确定运行时的资源路径,而不是直接使用固定路径。sys._MEIPASS 是 PyInstaller 在打包后提供的临时文件夹路径。
下面对 src 中的代码文件进行修改,由于源代码中对路径的引用都在 FlapPyBird\src\utils 这个文件夹下,所以只需要对其下代码修改。
以 images.py 为例,首先在首部加入:
import os
import sys
def get_resource_path(relative_path):
if hasattr(sys, '_MEIPASS'): # 当应用打包成exe时,使用 _MEIPASS 路径
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
然后在所有有路径的地方进行修改:
def __init__(self) -> None:
self.numbers = list(
(
#pygame.image.load(f"assets/sprites/{num}.png").convert_alpha()
pygame.image.load(get_resource_path(f"assets/sprites/{num}.png")).convert_alpha()
for num in range(10)
)
)
可以看到原代码是:
pygame.image.load(f"assets/sprites/{num}.png").convert_alpha()
改后为:
pygame.image.load(get_resource_path(f"assets/sprites/{num}.png")).convert_alpha()
在路径前加了 get_resource_path(),动态获取路径。同理,将所有有路径的代码均在路径前加入 get_resource_path() 即可。
修改后的完整代码如下:
import random
from typing import List, Tuple
import os
import sys
import pygame
from .constants import BACKGROUNDS, PIPES, PLAYERS
def get_resource_path(relative_path):
if hasattr(sys, '_MEIPASS'): # 当应用打包成exe时,使用 _MEIPASS 路径
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
class Images:
numbers: List[pygame.Surface]
game_over: pygame.Surface
welcome_message: pygame.Surface
base: pygame.Surface
background: pygame.Surface
player: Tuple[pygame.Surface]
pipe: Tuple[pygame.Surface]
def __init__(self) -> None:
self.numbers = list(
(
pygame.image.load(get_resource_path(f"assets/sprites/{num}.png")).convert_alpha()
for num in range(10)
)
)
# game over sprite
self.game_over = pygame.image.load(
get_resource_path("assets/sprites/gameover.png")
).convert_alpha()
# welcome_message sprite for welcome screen
self.welcome_message = pygame.image.load(
get_resource_path("assets/sprites/message.png")
).convert_alpha()
# base (ground) sprite
self.base = pygame.image.load(get_resource_path("assets/sprites/base.png")).convert_alpha()
self.randomize()
def randomize(self):
# select random background sprites
rand_bg = random.randint(0, len(BACKGROUNDS) - 1)
# select random player sprites
rand_player = random.randint(0, len(PLAYERS) - 1)
# select random pipe sprites
rand_pipe = random.randint(0, len(PIPES) - 1)
self.background = pygame.image.load(BACKGROUNDS[rand_bg]).convert()
self.player = (
pygame.image.load(PLAYERS[rand_player][0]).convert_alpha(),
pygame.image.load(PLAYERS[rand_player][1]).convert_alpha(),
pygame.image.load(PLAYERS[rand_player][2]).convert_alpha(),
)
self.pipe = (
pygame.transform.flip(
pygame.image.load(PIPES[rand_pipe]).convert_alpha(),
False,
True,
),
pygame.image.load(PIPES[rand_pipe]).convert_alpha(),
)
打包
最后使用以下命令进行打包:
pyinstaller --onefile --windowed --icon=flappy.ico --add-data "assets/sprites;assets/sprites" --add-data "assets/audio;assets/audio" main.py
如果你只需要exe文件,可以直接下载:https://download.csdn.net/download/2301_79442295/90096752?spm=1001.2014.3001.5503
运行效果如下:
热门推荐
专家推荐:三种深呼吸法助你缓解压力睡得香
CBT疗法详解:四大技术助你摆脱焦虑困扰
茶咖届新增强制检测项,这个成分为啥让人又爱又怕?
檀香茶的功效与作用及饮用禁忌
每天喝几杯茶好处最多?喝够这个量,能护大脑、抗衰老!
提升午睡质量:五款神器助力快速恢复精力
午睡时长影响老人抑郁风险,30-75分钟为最佳区间
午睡多久最有益?研究称30分钟最佳,可提升大脑效率
研究证实:30分钟午睡让大脑“重启”,降低心血管疾病风险
最新研究:午睡超1小时死亡风险增30%,专家建议控制在30分钟内
一次性领取失业金划算吗?
失业后医保如何保障?保障措施有哪些局限性?
麟游失业金领取多少钱?2025麟游失业金领取条件+发放标准
失业后社保如何续交
领失业金期间公司能交社保吗
数据说话,案例支撑:保洁主管年度总结写作攻略
高原圣湖木纳措:四季景观与最佳游览时间
基本保额和标准保费的区别
中国南大门珠三角,广州市周边旅游攻略,珠三角十佳优质景点推荐
看似低调,实则小吃超多,广东这座小城才是老饕心目中的美食圣地
从便便看健康:解读狗狗排便次数、颜色与形状标准
7天教会狗狗上厕所:简单实用的定点排便训练法
顾泽鑫和顾宴辰的高情商分手指南
湖北省中医院推出夏季去湿热方案,五大方面全面调理
甲醛鱼、柴油鱼、洗衣粉鱼:春节年货选购防坑指南
家庭养殖河蟹全攻略:六大环节打造理想养殖环境
新年必吃清蒸肘子:营养价值与制作步骤详解
闽南煎红蟹:六步做出鲜美蟹肉的烹饪指南
母蟹有蟹黄公蟹有蟹膏,教你一眼辨认螃蟹公母
从锡纸蒸到环形摆盘:清蒸鲈鱼的创意升级