Korzystając z doskonałej odpowiedzi od Maxa i tego postu na temat dodawania dodatkowych plików danych, takich jak obrazy lub dźwięk oraz moich własnych badań / testów, doszedłem do wniosku, że najłatwiej jest dodać takie pliki.
Jeśli chcesz zobaczyć przykład na żywo, moje repozytorium jest tutaj na GitHub.
Uwaga: dotyczy to kompilacji przy użyciu polecenia --onefile
lub -F
w programie pyinstaller.
Moje środowisko jest następujące.
Rozwiązanie problemu w 2 krokach
Aby rozwiązać ten problem, musimy wyraźnie powiedzieć Pyinstallerowi, że mamy dodatkowe pliki, które muszą być „dołączone” do aplikacji.
Musimy również używać ścieżki „względnej” , aby aplikacja działała poprawnie, gdy działa jako skrypt Pythona lub zamrożony EXE.
Mając to na uwadze, potrzebujemy funkcji, która pozwoli nam mieć ścieżki względne. Korzystając z funkcji, którą Max opublikował , możemy łatwo rozwiązać ścieżkę względną.
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)
Użylibyśmy powyższej funkcji w ten sposób, aby ikona aplikacji była wyświetlana, gdy aplikacja jest uruchomiona jako skrypt LUB zamrożony plik EXE.
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
Następnym krokiem jest to, że musimy poinstruować Pyinstaller, gdzie znaleźć dodatkowe pliki podczas kompilacji, aby po uruchomieniu aplikacji zostały utworzone w katalogu tymczasowym.
Możemy rozwiązać ten problem na dwa sposoby, jak pokazano w dokumentacji , ale ja osobiście wolę zarządzać własnym plikiem .spec, więc tak właśnie zamierzamy to zrobić.
Po pierwsze, musisz już mieć plik .spec. W moim przypadku udało mi się stworzyć to, co potrzebne, uruchamiając pyinstaller
z dodatkowymi argumentami można znaleźć dodatkowe argumenty tutaj . Z tego powodu mój plik specyfikacji może wyglądać trochę inaczej niż twój, ale zamieszczam go w całości w celach informacyjnych, po tym, jak wyjaśnię ważne elementy.
added_files to zasadniczo lista zawierająca krotki, w moim przypadku chcę dodać tylko POJEDYNCZY obraz, ale możesz dodać wiele ikon ico, png lub jpg używając('app/img/*.ico', 'app/img')
Możesz również utworzyć kolejną krotkę,added_files = [ (), (), ()]
aby mieć wiele importów
Pierwsza część krotki określa, jaki plik lub typ pliku chcesz dodać, a także gdzie je znaleźć. Pomyśl o tym jako CTRL + C
Druga część krotki mówi Pyinstallerowi, aby utworzył ścieżkę „app / img /” i umieścił pliki w tym katalogu Względem dowolnego katalogu tymczasowego, który zostanie utworzony po uruchomieniu pliku .exe. Pomyśl o tym jako CTRL + V
Poniżeja = Analysis([main...
ustawiłemdatas=added_files
, pierwotnie tak było,datas=[]
ale chcemy, aby lista importów była, cóż, zaimportowana, więc przekazujemy nasze niestandardowe importy.
Nie musisz tego robić, chyba że chcesz mieć określoną ikonę dla EXE, na dole pliku specyfikacji mówię Pyinstaller, aby ustawił ikonę mojej aplikacji na exe z opcją 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')
Kompilacja do EXE
Jestem bardzo leniwy; Nie lubię pisać rzeczy bardziej niż muszę. Utworzyłem plik .bat, który mogę po prostu kliknąć. Nie musisz tego robić, ten kod będzie działał w powłoce wiersza polecenia bez niego.
Ponieważ plik .spec zawiera wszystkie nasze ustawienia i argumenty kompilacji (czyli opcje), musimy tylko przekazać ten plik .spec do Pyinstaller.
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) naprawdę mi pomogła. dokumentacja pyinstallera mówi o używaniu,COLLECT
ale nie udaje się umieścić plików w binarnym podczas używania--onefile