Основной файл KV не может быть найден в Pyinstaller exe - PullRequest
0 голосов
/ 04 мая 2020

Я в своем уме ... Итак, у меня есть приложение kivy, которое отлично работает с интерпретатором и отлично работает при сборке в виде каталога. Но, похоже, неважно, как я его создаю, в результате исполняемый файл всегда не может найти мой файл main.kv. Моя файловая структура такова, что у меня в основном есть изображения и несколько экранов.

main.py
main.kv
resources/image 1
         /image 2
         /kv_files/screen1
                  /screen2 

Я уже задавал все подобные вопросы по SO, включая этот и этот и этот . Я думаю, что перепробовал все варианты, совсем недавно я добавил

def 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.environ.get("_MEIPASS2",os.path.abspath("."))

return os.path.join(base_path, relative_path)

в начало моего скрипта и

 resource_path('main.kv')

непосредственно перед app.run (). И в этот момент я чувствую, что попробовал любую другую комбинацию из разных предложений. Spe c file is

# -*- mode: python ; coding: utf-8 -*-
 from kivy_deps import sdl2, glew

block_cipher = None

a = Analysis(['C:\\Users\\nicks\\PycharmProjects\\Winapp\\main.py'],
         pathex=['C:\\Users\\nicks\\Desktop\\Winapp'],
         binaries=[],
         datas=[('C:\\Users\\nicks\\PycharmProjects\\Winapp\\main.kv', '.')],
         hiddenimports=['pkg_resources.py2_warn', 'win32timezone'],
         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)
a.datas += [('main.kv', 'C:/users/nicks/PyCharmProjects/Winapp/main.kv', 'DATA')]

exe = EXE(pyz, Tree('C:\\Users\\nicks\\PycharmProjects\\Winapp\\resources', 'DATA'),
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
      name='mainapp',
      debug=True,
      bootloader_ignore_signals=False,
      strip=False,
      upx=True,
      upx_exclude=[],
      runtime_tmpdir=None,
      console=True)

Кажется, что бы я ни пытался, командная строка дает мне

Traceback (most recent call last):
File "main.py", line 147, in <module>
File "lib\site-packages\kivy\lang\builder.py", line 288, in load_file
FileNotFoundError: [Errno 2] No such file or directory: 'main.kv'

, в случае его использования строка 147 будет

GUI = Builder.load_file('main.kv')

Итак, я понимаю, почему неспособность найти это проблема. Я ознакомился с документами PyInstaller о том, как a.datas и Tree должны быть структурированы, поэтому я думаю, что они в порядке, но я все еще чувствую, что есть кое-что фундаментальное, чего я не получаю. Любая помощь вообще с благодарностью получена ...

1 Ответ

1 голос
/ 04 мая 2020

Вот как я это делаю. В моем файле main.spec я указываю свой файл kv следующим образом:

         datas=[('gamescreen.kv', '.')]

Поскольку он находится в той же папке, что и мой main.py, полный путь не требуется.

Чтобы добавить sys._MEIPASS к пути к ресурсу, я использую (вверху main.py):

if getattr(sys, 'frozen', False):
    # this is a Pyinstaller bundle
    kivy.resources.resource_add_path(sys._MEIPASS)

Также просто напоминание о том, что pyinstaller ведет себя странно в отношении команды Строковые аргументы. Обратите внимание на документацию , в которой обсуждаются ограниченные параметры, которые действительно действуют при запуске pyinstaller с файлом .spec в качестве аргумента. В этом случае некоторые параметры командной строки игнорируются.

...