Mit der hervorragenden Antwort von Max und diesem Beitrag über das Hinzufügen zusätzlicher Datendateien wie Bilder oder Ton und meine eigenen Recherchen / Tests habe ich herausgefunden, was meiner Meinung nach der einfachste Weg ist, solche Dateien hinzuzufügen.
Wenn Sie ein Live-Beispiel sehen möchten, ist mein Repository hier auf GitHub.
Hinweis: Dies dient zum Kompilieren mit dem Befehl --onefile
oder -F
mit pyinstaller.
Meine Umgebung ist wie folgt.
Lösen des Problems in 2 Schritten
Um das Problem zu lösen, müssen wir Pyinstaller ausdrücklich mitteilen, dass wir zusätzliche Dateien haben, die mit der Anwendung "gebündelt" werden müssen.
Wir müssen auch einen "relativen" Pfad verwenden , damit die Anwendung ordnungsgemäß ausgeführt werden kann, wenn sie als Python-Skript oder als Frozen EXE ausgeführt wird.
Wenn dies gesagt ist, brauchen wir eine Funktion, die es uns ermöglicht, relative Pfade zu haben. Mit der Funktion Max Posted können wir die relative Pfadbildung leicht lösen.
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)
Wir würden die obige Funktion wie folgt verwenden, damit das Anwendungssymbol angezeigt wird, wenn die App entweder als Skript oder als eingefrorene EXE ausgeführt wird.
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
Der nächste Schritt besteht darin, Pyinstaller anzuweisen, wo die zusätzlichen Dateien beim Kompilieren zu finden sind, damit sie beim Ausführen der Anwendung im temporären Verzeichnis erstellt werden.
Wir können dieses Problem auf zwei Arten lösen, wie in der Dokumentation gezeigt , aber ich persönlich bevorzuge es, meine eigene .spec-Datei zu verwalten, damit wir es so machen.
Zunächst müssen Sie bereits eine .spec-Datei haben. In meinem Fall konnte ich das erstellen, was ich brauchte, indem ich pyinstaller
mit zusätzlichen Argumenten lief. Weitere Argumente finden Sie hier . Aus diesem Grund sieht meine Spezifikationsdatei möglicherweise etwas anders aus als Ihre, aber ich poste sie alle als Referenz, nachdem ich die wichtigen Teile erklärt habe.
added_files ist im Wesentlichen eine Liste mit Tupeln. In meinem Fall möchte ich nur ein EINZELNES Bild hinzufügen, aber Sie können mehrere Icos, PNGs oder JPGs hinzufügen.('app/img/*.ico', 'app/img')
Sie können auch ein anderes Tupel erstellenadded_files = [ (), (), ()]
, um mehrere Importedurchzuführen
Der erste Teil des Tupels definiert, welche Datei oder welchen Dateityp Sie hinzufügen möchten und wo Sie sie finden. Stellen Sie sich dies als STRG + C vor
Der zweite Teil des Tupels weist Pyinstaller an, den Pfad 'app / img /' zu erstellen und die Dateien in diesem Verzeichnis RELATIV zu dem temporären Verzeichnis abzulegen, das beim Ausführen der EXE-Datei erstellt wird. Stellen Sie sich dies als STRG + V vor
Untera = Analysis([main...
mir festgelegt habedatas=added_files
,ursprünglich verwendetes zu seindatas=[]
aber wir wollenum die Liste der Importe aus, na ja, importiertso dass wir in unseren eigenen Importen passieren.
Sie müssen dies nur tun, wenn Sie ein bestimmtes Symbol für die EXE-Datei möchten. Am Ende der Spezifikationsdatei fordere ich Pyinstaller auf, mein Anwendungssymbol für die Exe mit der Option festzulegen 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')
Kompilieren zu EXE
Ich bin sehr faul; Ich mag es nicht mehr Dinge zu tippen als ich muss. Ich habe eine .bat-Datei erstellt, auf die ich einfach klicken kann. Sie müssen dies nicht tun, dieser Code wird ohne ihn in einer Eingabeaufforderungs-Shell ausgeführt.
Da die .spec-Datei alle unsere Kompilierungseinstellungen und -argumente (auch als Optionen bezeichnet) enthält, müssen wir diese .spec-Datei nur Pyinstaller übergeben.
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) hat mir gerade wirklich geholfen. In der Pyinstaller-Dokumentation wird über die Verwendung gesprochen,COLLECT
aber bei der Verwendung werden keine Dateien in die Binärdatei--onefile