[英]Pyinstaller is unable to run a Kivy Application due to KeyError
我正在使用 pyinstaller 打包 Kivy 应用程序。 原始应用程序工作正常,但从 dist 文件夹运行时,由于关键错误而失败。 具体来说,它启动了 Kivy 应用程序,但随后由于密钥错误而立即关闭。
错误信息:
Traceback (most recent call last):
File "kivy\properties.pyx", line 861, in kivy.properties.ObservableDict.__getattr__
KeyError: 'screen_login'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "cli.py", line 5, in <module>
File "kivy\app.py", line 949, in run
File "kivy\app.py", line 919, in _run_prepare
File "src\__main__.py", line 26, in build
File "src\__main__.py", line 20, in __init__
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
添加了带有资源路径 function 的 main.py。
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
import os
import sys
from kivy.resources import resource_add_path, resource_find
# Import files like
from CheckIn_Application.src.screens.login.login import LoginScreen
from CheckIn_Application.src.screens.checkin.checkin import CheckInScreen
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.path.abspath(".")
return os.path.join(base_path, relative_path)
# Make all stuff modular
class WindowManager(BoxLayout):
# Class Widgets
login_widget = LoginScreen()
check_in_widget = CheckInScreen()
print(resource_path('maincheckin.kv'))
def __init__(self, **kwargs):
super().__init__(**kwargs)
# super(WindowManager, self).__init__(**kwargs)
# Add Widget
self.ids.screen_login.add_widget(self.login_widget)
self.ids.screen_checkin.add_widget(self.check_in_widget)
class MainCheckin(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
# Main().run()
if hasattr(sys, '_MEIPASS'):
resource_add_path(os.path.join(sys._MEIPASS))
MainCheckin().run()
以及关联的.kv 文件
<WindowManager>:
id: main_window
ScreenManager:
id: scrn_mngr_main
Screen:
id: screen_login
name:'screen_login'
Screen:
id: screen_checkin
name:'screen_checkin'
我认为这与 pyinstaller 如何与 .kv 文件交互有关。 当我在原始代码中将屏幕的 id 更改为字符串(即 id:“screen_login 与 id:screen_login”)时,我可以复制此错误。我认为 Kivy 指出不将其元素 id 标识为字符串。
编辑:规格文件:
# -*- mode: python ; coding: utf-8 -*-
import os
import sys
from pathlib import Path
from pylibdmtx import pylibdmtx
from pyzbar import pyzbar
from kivy_deps import sdl2, glew
block_cipher = None
a = Analysis(
['cli.py'],
pathex=['C:/Users/username/PycharmProjects/DBlytics/CheckIn_Application'],
binaries=[],
datas=[('C:/Users/username/PycharmProjects/DBlytics/CheckIn_Application/src/maincheckin.kv','.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
# dylibs are not detected because loaded by ctypes.
# binaries accept the TOC format. Use list comprehension.
a.binaries += TOC([
(Path(dep._name).name, dep._name, 'BINARY')
for dep in pylibdmtx.EXTERNAL_DEPENDENCIES + pyzbar.EXTERNAL_DEPENDENCIES
])
# A dependency of libzbar.dylib that PyInstaller does not detect
MISSING_DYLIBS = (
Path('/usr/local/lib/libjpeg.8.dylib'),
)
a.binaries += TOC([
(lib.name, str(lib.resolve()), 'BINARY') for lib in MISSING_DYLIBS
])
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
a.datas += [('maincheckin.kv', 'C:/Users/username/PycharmProjects/DBlytics/CheckIn_Application/src/maincheckin.kv', 'DATA')]
exe = EXE(
pyz,
a.scripts,
# *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
[],
exclude_binaries=True,
name='cli',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
upx_exclude=[],
name='cli')
在此方法中将 .kv 文件添加到规范时,我注意到 pyinstaller 将 .kv 文件添加到 dist\cli\ 文件夹而不是 _MEIPASS 临时文件夹。
问题是我的原始代码是正确的,但是在我 package 之后,这个错误就会被抛出。
你可以和我分享 your.spec 文件吗? 几周前我遇到了同样的问题。 我认为您没有指定数据源。
My.spec 文件位于:../denul2/ 我的代码文件 (.py/.kv) 位于:../denul2/project/
看这个: https://imgur.com/a/pWCKPQ1
编辑:尝试也添加这个: https://imgur.com/a/rGFOMw5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.