Usando l'eccellente risposta di Max e questo post sull'aggiunta di file di dati extra come immagini o suoni e la mia ricerca / test, ho capito quello che credo sia il modo più semplice per aggiungere tali file.
Se desideri vedere un esempio dal vivo, il mio repository è qui su GitHub.
Nota: serve per la compilazione utilizzando il comando --onefile
o -F
con pyinstaller.
Il mio ambiente è il seguente.
Risolvere il problema in 2 passaggi
Per risolvere il problema dobbiamo dire specificamente a Pyinstaller che abbiamo file extra che devono essere "raggruppati" con l'applicazione.
È inoltre necessario utilizzare un percorso "relativo" , in modo che l'applicazione possa essere eseguita correttamente quando viene eseguita come script Python o EXE congelato.
Detto questo, abbiamo bisogno di una funzione che ci consenta di avere percorsi relativi. Utilizzando la funzione che Max Posted possiamo risolvere facilmente il percorso relativo.
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)
Useremo la funzione sopra in questo modo in modo che l'icona dell'applicazione venga visualizzata quando l'app è in esecuzione come script o come EXE congelato.
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
Il passo successivo è che dobbiamo istruire Pyinstaller su dove trovare i file extra durante la compilazione in modo che quando l'applicazione viene eseguita, vengano creati nella directory temporanea.
Possiamo risolvere questo problema in due modi, come mostrato nella documentazione , ma personalmente preferisco gestire il mio file .spec, quindi è così che lo faremo.
Innanzitutto, devi già avere un file .spec. Nel mio caso, sono stato in grado di creare ciò di cui avevo bisogno eseguendo pyinstaller
argomenti extra, puoi trovare argomenti extra qui . Per questo motivo, il mio file delle specifiche potrebbe sembrare leggermente diverso dal tuo, ma lo pubblicherò tutto come riferimento dopo aver spiegato le parti importanti.
added_files è essenzialmente una lista contenente Tuple, nel mio caso voglio solo aggiungere una SINGOLA immagine, ma puoi aggiungere più ico, png o jpg usando('app/img/*.ico', 'app/img')
Puoi anche creare un'altra tupla in questo modoadded_files = [ (), (), ()]
per avere più importazioni
La prima parte della tupla definisce quale file o quale tipo di file si desidera aggiungere e dove trovarli. Pensa a questo come CTRL + C
La seconda parte della tupla dice a Pyinstaller di creare il percorso "app / img /" e di posizionare i file in quella directory RELATIVI a qualsiasi directory temporanea creata quando si esegue l'exe. Pensa a questo come CTRL + V
Sottoa = Analysis([main...
, ho impostatodatas=added_files
, originariamente eradatas=[]
ma vogliamo che l'elenco delle importazioni sia, beh, importato, quindi passiamo alle nostre importazioni personalizzate.
Non è necessario farlo a meno che non si desideri un'icona specifica per l'EXE, in fondo al file delle specifiche sto dicendo a Pyinstaller di impostare l'icona della mia applicazione per l'exe con l'opzione 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')
Compilazione in EXE
Sono molto pigro; Non mi piace scrivere cose più di quanto devo. Ho creato un file .bat su cui posso semplicemente fare clic. Non devi farlo, questo codice verrà eseguito in una shell del prompt dei comandi senza di essa.
Dato che il file .spec contiene tutte le nostre impostazioni e argomenti di compilazione (ovvero opzioni), dobbiamo solo dare quel file .spec a Pyinstaller.
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) mi ha davvero aiutato proprio ora. la documentazione di pyinstaller parla dell'usoCOLLECT
ma non riesce a mettere i file nel binario durante l'utilizzo--onefile