Используя отличный ответ от Макса и этот пост о добавлении дополнительных файлов данных, таких как изображения или звук, а также мое собственное исследование / тестирование, я выяснил, что, по моему мнению, является самым простым способом добавления таких файлов.
Если вы хотите увидеть живой пример, мой репозиторий находится здесь, на GitHub.
Примечание: это для компиляции с использованием команды --onefile
или -F
с pyinstaller.
Моя среда выглядит следующим образом.
Решение проблемы в 2 шага
Чтобы решить эту проблему, нам нужно специально сообщить Pyinstaller, что у нас есть дополнительные файлы, которые необходимо «связать» с приложением.
Нам также необходимо использовать «относительный» путь , чтобы приложение могло работать правильно, когда оно выполняется как скрипт Python или замороженный EXE.
При этом нам нужна функция, которая позволяет нам иметь относительные пути. Используя функцию, которую опубликовал Макс, мы можем легко решить относительный путь.
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)
Мы бы использовали указанную выше функцию таким образом, чтобы значок приложения отображался, когда приложение работает либо как сценарий, либо как замороженный EXE.
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
Следующим шагом является то, что нам нужно указать Pyinstaller, где найти дополнительные файлы при его компиляции, чтобы при запуске приложения они создавались во временном каталоге.
Мы можем решить эту проблему двумя способами, как показано в документации , но я лично предпочитаю управлять своим собственным файлом .spec, так что мы собираемся это сделать.
Во-первых, у вас уже должен быть файл .spec. В моем случае я смог создать то, что мне нужно, запустив pyinstaller
дополнительные аргументы, вы можете найти дополнительные аргументы здесь . Из-за этого мой файл спецификаций может немного отличаться от вашего, но я публикую его для справки после того, как объясню важные моменты.
added_files - это, по сути, список, содержащий кортежи, в моем случае я хочу добавить только ОДНО изображение, но вы можете добавить несколько ico, png или jpg, используя('app/img/*.ico', 'app/img')
Вы также можете создать другой кортеж, например, чтобыadded_files = [ (), (), ()]
иметь несколько импортов
Первая часть кортежа определяет, какой файл или какой тип файла вы хотите добавить, а также где их найти. Думайте об этом как о CTRL + C
Вторая часть кортежа сообщает Pyinstaller, что нужно сделать путь app / img / и поместить файлы в этот каталог ОТНОСИТЕЛЬНО к тому временному каталогу, который создается при запуске .exe. Думайте об этом как о CTRL + V
Подa = Analysis([main...
, я установилdatas=added_files
, изначально это было,datas=[]
но мы хотим, чтобы список импорта был ... ну, импортирован, поэтому мы передаем наши пользовательские импорты.
Вам не нужно этого делать, если вам не нужен конкретный значок для EXE, в нижней части файла спецификации я говорю Pyinstaller, чтобы установить значок моего приложения для exe с опцией 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')
Компиляция в EXE
Я очень ленив; Я не люблю печатать больше, чем должен. Я создал файл .bat, по которому можно просто щелкнуть. Вам не нужно этого делать, этот код будет отлично работать и без него в командной строке.
Поскольку файл .spec содержит все наши параметры компиляции и аргументы (также известные как параметры), нам просто нужно передать этот файл .spec в Pyinstaller.
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) действительно помогла мне только что. в документации по pyinstaller говорится об использовании,COLLECT
но при использовании не удается поместить файлы в двоичный файл--onefile