如何解决ValueError: KivyMD应用需继承自kivymd.app.MDApp?
KivyMD热重载应用报错:ValueError: KivyMD: App object must be inherited from
kivymd.app.MDApp 问题场景
使用Kaki/KivyMD开发热重载应用,运行live.py时触发上述报错,相关代码及报错回溯如下:
main.py代码
from kivymd.app import MDApp from kivy.lang import Builder from kivy.core.window import Window from kivy.factory import Factory as F Window.size = 360,640 class UI(F.ScreenManager): Builder.load_file("layout.kv") class Main(MDApp): def build(self): return UI() if __name__ == "__main__": Main().run()
live.py代码
from kaki.app import App from kivy.factory import Factory as F import os class Live(App): CLASSES = { "UI": "main" } KV_FILES = { os.path.join(os.getcwd(),"layout.kv") } AUTORELOADER_PATHS = [ (".", {"recursive": True}), ] def build_app(self, first=False): return F.UI() Live().run()
layout.kv代码
<UI> Screen: MDLabel: text: "hello"
运行命令
set DEBUG=1 ; python live.py
完整报错回溯
(venv) PS C:\Users\Cipher\PycharmProjects\AppliStage> set DEBUG=1 ; python live.py [INFO ] [Logger ] Record log in C:\Users\Cipher\.kivy\logs\kivy_22-07-30_22.txt [INFO ] [deps ] Successfully imported "kivy_deps.angle" 0.3.2 [INFO ] [deps ] Successfully imported "kivy_deps.glew" 0.3.1 [INFO ] [deps ] Successfully imported "kivy_deps.sdl2" 0.4.5 [INFO ] [Kivy ] v2.1.0 [INFO ] [Kivy ] Installed at "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\__init__.py" [INFO ] [Python ] v3.9.10 (tags/v3.9.10:f2f3f53, Jan 17 2022, 15:14:21) [MSC v.1929 64 bit (AMD64)] [INFO ] [Python ] Interpreter at "C:\Users\Cipher\PycharmProjects\AppliStage\venv\Scripts\python.exe" [INFO ] [Logger ] Purge log fired. Processing... [INFO ] [Logger ] Purge finished! [INFO ] [Factory ] 189 symbols loaded [INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored) [INFO ] [Window ] Provider: sdl2 [INFO ] [GL ] Using the "OpenGL" graphics system [INFO ] [GL ] GLEW initialization succeeded [INFO ] [GL ] Backend used <glew> [INFO ] [GL ] OpenGL version <b'4.6.0 - Build 30.0.101.1340'> [INFO ] [GL ] OpenGL vendor <b'Intel'> [INFO ] [GL ] OpenGL renderer <b'Intel(R) HD Graphics 620'> [INFO ] [GL ] OpenGL parsed version: 4, 6 [INFO ] [GL ] Shading version <b'4.60 - Build 30.0.101.1340'> [INFO ] [GL ] Texture max size <16384> [INFO ] [GL ] Texture max units <32> [INFO ] [Window ] auto add sdl2 input provider [INFO ] [Window ] virtual keyboard not allowed, single mode, not docked [INFO ] [KivyMD ] 0.104.2, git-bc7d1f5, 2021-06-06 (installed at "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivymd\__init__.py") [INFO ] [Text ] Provider: sdl2 [WARNING] [Lang ] The file C:\Users\Cipher\PycharmProjects\AppliStage\layout.kv is loaded multiples times, you might have unwanted behaviors. --- Logging error --- Traceback (most recent call last): File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kaki\app.py", line 163, in rebuild self.approot = self.build_app() File "C:\Users\Cipher\PycharmProjects\AppliStage\live.py", line 19, in build_app return F.UI() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\screenmanager.py", line 973, in __init__ super(ScreenManager, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\floatlayout.py", line 65, in __init__ super(FloatLayout, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\layout.py", line 76, in __init__ super(Layout, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\widget.py", line 366, in __init__ self.apply_class_lang_rules( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\widget.py", line 470, in apply_class_lang_rules Builder.apply( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 540, in apply self._apply_rule( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 662, in _apply_rule self._apply_rule( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 658, in _apply_rule child = cls(__no_builder=True) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivymd\uix\label.py", line 324, in __init__ super().__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivymd\theming.py", line 1129, in __init__ raise ValueError( ValueError: KivyMD: App object must be inherited from `kivymd.app.MDApp` During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py", line 1083, in emit msg = self.format(record) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py", line 927, in format return fmt.format(record) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\logger.py", line 291, in format record = copy.deepcopy(record) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 172, in deepcopy y = _reconstruct(x, memo, *rv) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 270, in _reconstruct state = deepcopy(state, memo) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 146, in deepcopy y = copier(x, memo) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 230, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 146, in deepcopy y = copier(x, memo) File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 210, in _deepcopy_tuple y = [deepcopy(a, memo) for a in x] File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 210, in <listcomp> y = [deepcopy(a, memo) for a in x] File "C:\Users\Cipher\AppData\Local\Programs\Python\Python39\lib\copy.py", line 161, in deepcopy rv = reductor(4) TypeError: cannot pickle 'traceback' object Call stack: File "C:\Users\Cipher\PycharmProjects\AppliStage\live.py", line 21, in <module> Live().run() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\app.py", line 954, in run self._run_prepare() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\app.py", line 924, in _run_prepare root = self.build() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kaki\app.py", line 101, in build self.rebuild(first=True) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kaki\app.py", line 168, in rebuild Logger.exception("{}: Error when building app".format(self.appname)) Message: 'Live: Error when building app' Arguments: () Traceback (most recent call last): File "C:\Users\Cipher\PycharmProjects\AppliStage\live.py", line 21, in <module> Live().run() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\app.py", line 954, in run self._run_prepare() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\app.py", line 924, in _run_prepare root = self.build() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kaki\app.py", line 101, in build self.rebuild(first=True) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kaki\app.py", line 163, in rebuild self.approot = self.build_app() File "C:\Users\Cipher\PycharmProjects\AppliStage\live.py", line 19, in build_app return F.UI() File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\screenmanager.py", line 973, in __init__ super(ScreenManager, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\floatlayout.py", line 65, in __init__ super(FloatLayout, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\layout.py", line 76, in __init__ super(Layout, self).__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\widget.py", line 366, in __init__ self.apply_class_lang_rules( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\uix\widget.py", line 470, in apply_class_lang_rules Builder.apply( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 540, in apply self._apply_rule( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 662, in _apply_rule self._apply_rule( File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivy\lang\builder.py", line 658, in _apply_rule child = cls(__no_builder=True) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivymd\uix\label.py", line 324, in __init__ super().__init__(**kwargs) File "C:\Users\Cipher\PycharmProjects\AppliStage\venv\lib\site-packages\kivymd\theming.py", line 1129, in __init__ raise ValueError( ValueError: KivyMD: App object must be inherited from `kivymd.app.MDApp`
解决方法
核心原因
KivyMD的组件(如MDLabel)要求应用类必须继承自kivymd.app.MDApp,但当前live.py中的Live类继承的是普通的kaki.app.App(基于Kivy原生App),不满足KivyMD的依赖要求。
修改步骤
- 更新live.py代码
将Live类改为多重继承MDApp和kaki的App,同时调整导入语句:
from kivymd.app import MDApp from kaki.app import App as KakiApp from kivy.factory import Factory as F import os class Live(MDApp, KakiApp): CLASSES = { "UI": "main" } KV_FILES = { os.path.join(os.getcwd(),"layout.kv") } AUTORELOADER_PATHS = [ (".", {"recursive": True}), ] def build_app(self, first=False): return F.UI() Live().run()
- 优化main.py的kv加载方式(可选)
原代码中在UI类定义内加载kv文件会触发重复加载警告,建议将加载语句移到类外:
from kivymd.app import MDApp from kivy.lang import Builder from kivy.core.window import Window from kivy.factory import Factory as F Window.size = 360,640 # 移到类外加载kv文件 Builder.load_file("layout.kv") class UI(F.ScreenManager): pass class Main(MDApp): def build(self): return UI() if __name__ == "__main__": Main().run()
完成修改后,重新运行set DEBUG=1 ; python live.py即可正常启动热重载应用。
内容的提问来源于stack exchange,提问作者mathieu njembe
相关产品推荐
相关产品推荐

