En utilisant l'excellente réponse de Max et de cet article sur l'ajout de fichiers de données supplémentaires comme des images ou du son et mes propres recherches / tests, j'ai compris ce que je pense être le moyen le plus simple d'ajouter de tels fichiers.
Si vous souhaitez voir un exemple en direct, mon référentiel est ici sur GitHub.
Remarque: ceci est pour la compilation à l'aide de la commande --onefile
ou -F
avec pyinstaller.
Mon environnement est le suivant.
Résoudre le problème en 2 étapes
Pour résoudre le problème, nous devons spécifiquement indiquer à Pyinstaller que nous avons des fichiers supplémentaires qui doivent être «regroupés» avec l'application.
Nous devons également utiliser un chemin `` relatif '' pour que l'application puisse fonctionner correctement lorsqu'elle s'exécute en tant que script Python ou EXE gelé.
Cela étant dit, nous avons besoin d'une fonction qui nous permet d'avoir des chemins relatifs. En utilisant la fonction que Max Posté, nous pouvons facilement résoudre le chemin relatif.
def img_resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Nous utiliserions la fonction ci-dessus comme celle-ci afin que l'icône de l'application s'affiche lorsque l'application s'exécute en tant que script OU EXE gelé.
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
L'étape suivante est que nous devons indiquer à Pyinstaller où trouver les fichiers supplémentaires lors de la compilation afin que lorsque l'application est exécutée, ils soient créés dans le répertoire temporaire.
Nous pouvons résoudre ce problème de deux manières, comme indiqué dans la documentation , mais je préfère personnellement gérer mon propre fichier .spec, c'est ainsi que nous allons le faire.
Tout d'abord, vous devez déjà disposer d'un fichier .spec. Dans mon cas, j'ai pu créer ce dont j'avais besoin en exécutant pyinstaller
des arguments supplémentaires, vous pouvez trouver des arguments supplémentaires ici . Pour cette raison, mon fichier de spécifications peut sembler un peu différent du vôtre, mais je le poste tout pour référence après avoir expliqué les éléments importants.
added_files est essentiellement une liste contenant des tuple, dans mon cas, je ne veux ajouter qu'une seule image, mais vous pouvez ajouter plusieurs ico, png ou jpg en utilisant('app/img/*.ico', 'app/img')
Vous pouvez également créer un autre tuple comme ceciadded_files = [ (), (), ()]
pour avoir plusieurs importations
La première partie du tuple définit quel fichier ou quel type de fichier vous souhaitez ajouter ainsi que où les trouver. Considérez cela comme CTRL + C
La deuxième partie du tuple indique à Pyinstaller de créer le chemin «app / img /» et de placer les fichiers dans ce répertoire RELATIF au répertoire temporaire créé lorsque vous exécutez le .exe. Considérez cela comme CTRL + V
Sousa = Analysis([main...
, j'ai définidatas=added_files
, à l'origine c'était le cas,datas=[]
mais nous voulons que la liste des importations soit, eh bien, importée, donc nous passons dans nos importations personnalisées.
Vous n'avez pas besoin de le faire à moins que vous ne vouliez une icône spécifique pour l'EXE, au bas du fichier de spécifications, je dis à Pyinstaller de définir l'icône de mon application pour l'exe avec l'option icon='app\\img\\app_icon.ico'
.
added_files = [
('app/img/app_icon.ico','app/img/')
]
a = Analysis(['main.py'],
pathex=['D:\\Github Repos\\Processes-Killer\\Process Killer'],
binaries=[],
datas=added_files,
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,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Process Killer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True , uac_admin=True, icon='app\\img\\app_icon.ico')
Compilation en EXE
Je suis très paresseux; Je n'aime pas taper plus que nécessaire. J'ai créé un fichier .bat sur lequel je peux simplement cliquer. Vous n'êtes pas obligé de le faire, ce code fonctionnera très bien dans un shell d'invite de commande sans cela.
Puisque le fichier .spec contient tous nos paramètres de compilation et arguments (aka options), nous devons simplement donner ce fichier .spec à Pyinstaller.
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) m'a vraiment aidé à l'instant. la documentation pyinstaller parle de l'utilisationCOLLECT
mais cela ne parvient pas à mettre les fichiers dans le binaire lors de l'utilisation--onefile