Problem
Próbuję użyć PyInstaller do utworzenia aplikacji do użytku wewnętrznego w mojej firmie. Skrypt działa świetnie z działającego środowiska Pythona, ale traci coś po przetłumaczeniu na pakiet.PyInstaller, jak dołączyć pliki danych z zewnętrznego pakietu, który został zainstalowany przez pip?
W jaki sposób dołączać i odwoływać pliki danych, które sam potrzebuję w moim pakiecie, ale mam problemy z włączaniem lub odwoływaniem się do plików, które powinny wejść po zaimportowaniu.
Używam instalowanego na paczce pakietu o nazwie tk-tools, który zawiera kilka ładnych obrazów na panelowe wyświetlacze (wygląda jak diody LED). Problem polega na tym, że kiedy utworzyć skrypt pyinstaller, za każdym razem, jeden z tych obrazów jest odwołanie, otrzymuję błąd:
DEBUG:aspen_comm.display:COM23 19200
INFO:aspen_comm.display:adding pump 1 to the pump list: [1]
DEBUG:aspen_comm.display:updating interrogation list: [1]
Exception in Tkinter callback
Traceback (most recent call last):
File "tkinter\__init__.py", line 1550, in __call__
File "aspen_comm\display.py", line 206, in add
File "aspen_comm\display.py", line 121, in add
File "aspen_comm\display.py", line 271, in __init__
File "aspen_comm\display.py", line 311, in __init__
File "lib\site-packages\tk_tools\visual.py", line 277, in __init__
File "lib\site-packages\tk_tools\visual.py", line 289, in to_grey
File "lib\site-packages\tk_tools\visual.py", line 284, in _load_new
File "tkinter\__init__.py", line 3394, in __init__
File "tkinter\__init__.py", line 3350, in __init__
_tkinter.TclError: couldn't open "C:\_code\tools\python\aspen_comm\dist\aspen_comm\tk_tools\img/led-grey.png": no such file or directory
I wyglądał w tym katalogu w ostatniej linii - czyli tam, gdzie moja dystrybucja znajduje się - i okazało się, że nie ma katalogu tk_tools
.
Pytanie
Jak uzyskać pyinstaller zebrać pliki danych importowanych pakietów?
Spec pliku
Obecnie mój datas
jest pusty. Spec plik, stworzony z pyinstaller -n aspen_comm aspen_comm/__main__.py
:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['aspen_comm\\__main__.py'],
pathex=['C:\\_code\\tools\\python\\aspen_comm'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='aspen_comm',
debug=False,
strip=False,
upx=True,
console=True)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='aspen_comm')
Kiedy patrzę w ciągu /build/aspen_comm/out00-Analysis.toc
i /build/aspen_comm/out00-PYZ.toc
, znaleźć wpis, który wygląda jak stwierdzono pakiet tk_tools
. Dodatkowo istnieją funkcje pakietu tk_tools
, które działają idealnie przed dotarciem do punktu znajdowania plików danych, więc wiem, że jest on importowany gdzieś, po prostu nie wiem gdzie. Kiedy robię wyszukiwania dla tk_tools
, nie mogę znaleźć odniesienia do niego w strukturze pliku.
Próbowałem również opcji --hidden-imports
z takimi samymi wynikami.
częściowe rozwiązanie
Gdybym „ręcznie” dodać ścieżkę do pliku spec użyciu datas = [('C:\\_virtualenv\\aspen\\Lib\\site-packages\\tk_tools\\img\\', 'tk_tools\\img\\')]
i datas=datas
w Analysis
, to wszystkie prace zgodnie z oczekiwaniami. To zadziała, ale wolałbym, aby PyInstaller znalazł dane pakietu, ponieważ jest on wyraźnie zainstalowany. Będę szukał rozwiązania, ale - na razie - prawdopodobnie wykorzystam to nieidealne rozwiązanie.
Jeśli masz kontrolę nad pakietem ...
Następnie można użyć stringify na podpakiecie, ale to działa tylko jeśli jest to twój własny pakiet.
Jeśli dobrze rozumiem, to, co chcesz oprócz tego rozwiązania https://stackoverflow.com/a/31966932/4724196 to metoda automatycznego wykrywania statycznych plików 'tk_tools', czy to prawda? – HassenPy
@HassenPy Tak, ale podejrzewam, że automatyczne wykrywanie jest już częścią pakietu PyInstaller, po prostu nie znalazłem poprawnej składni. Łączone rozwiązanie nadal ma bezwzględną ścieżkę dla plików statycznych zakodowanych w pliku '.spec'. Miałem wrażenie, że pakiety 'pip installed' powinny zostać wciągnięte do PyInstaller przy niewielkim wysiłku, ale to najwyraźniej tak nie jest. Dziękuję za uwagę! – slightlynybbled