Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

python - Pyinstaller Unable to access Data Folder

Below is the game.spec file that I have created. When running the below command, the app gets created perfectly

pyinstaller --onefile game.spec

When operating the game, it is unable to locate any of the datafiles. On further exploration found that it searches for all the datafiles in the directory /Users/username and not from the absolute path the program runs from.

Does the spec file need to be written differently?

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['game.py'],
             pathex=['/Users/username/pythonenv/mygame'],
             binaries=[],
             datas=[('images','images'),
('fonts','fonts'),
('sounds','sounds'),
('pygame','pygame'),
('pygameMenu','pygameMenu'),
('pgzero','pgzero'),
('numpy','numpy'),
('pgzrun.py','.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='game',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='game')
app = BUNDLE(coll,
             name='game.app',
             icon=None,
             bundle_identifier=None)
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When pyInstaller (or cx_Freeze, py2exe, etc.) make an executable, all the program files, along with PyGame, Python and a bunch of other stuff is all compressed up.

When it's run, the first thing to happen is that archive of stuff is unpacked. Unpacked somewhere. Then your executable is started, but not from the location of the unpack.

To fix this, your script has to determine the location it is running from - that is the full path to the script. Then use this location to find all the program's extra files.

import sys
import os.path

if getattr(sys, 'frozen', False):
    EXE_LOCATION = os.path.dirname( sys.executable ) # cx_Freeze frozen
else:
    EXE_LOCATION = os.path.dirname( os.path.realpath( __file__ ) ) # Other packers

Then when loading a file, determine the full path with os.path.join:

my_image_filename = os.path.join( EXE_LOCATION, "images", "xenomorph.png" )
image = pygame.image.load( my_image_filename ).convert_alpha()

my_sound_filename = os.path.join( EXE_LOCATION, "sounds", "meep-meep.ogg" )
meep_sound = pygame.mixer.Sound( my_sound_filename )

It may be possible to use os.chdir( EXE_LOCATION ) to set the directory once, and thus make less changes, but I think being careful about paths is the best approach.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...