KivyMD报错App需在根组件前初始化及Screen与App类变量共享咨询
问题原因
- build方法执行顺序错误:你在调用
Builder.load_string(kv)加载KV组件树之前,就尝试访问root.manager,此时root组件尚未创建,同时App初始化流程还没完成,触发KivyMD的校验规则抛出异常。 - 冗余代码冲突:全局额外创建了
sm = ScreenManager()实例,和KV中定义的ScreenManager重复,完全没有实际作用,还会导致组件实例混乱。 - 跨组件传值方式不合理:直接通过manager索引访问其他Screen的ids,耦合度极高,也无法实现App和Screen之间的变量共享需求。
修复方案
- 先删除全局无用的ScreenManager实例相关代码
- 调整build方法执行顺序:先加载KV得到root实例,再进行组件操作
- 在MDApp子类中定义Kivy属性作为共享变量,所有Screen都可以通过
MDApp.get_running_app()获取当前App实例,读写该属性即可实现跨Screen、Screen和App之间的变量共享。
完整可运行代码
from kivymd.app import MDApp from kivy.lang.builder import Builder from kivy.uix.screenmanager import Screen, ScreenManager from kivy.properties import StringProperty kv =''' ScreenManager: Fscr: Sscr: <Fscr>: name:'fscr' MDTextField: id:inp hint_text:'File location' pos_hint:{'center_x':0.5,'center_y':0.5} MDRoundFlatButton: text:'To Second Screen' pos_hint:{'center_x':0.3,'center_y':0.3} on_press: # 把输入值存到App的共享属性里 app.shared_text = root.ids.inp.text root.manager.current='sscr' <Sscr>: name:'sscr' MDLabel: # 直接绑定App的共享属性,值变了自动更新 text: app.shared_text pos_hint:{'center_x':0.5,'center_y':0.5} MDRoundFlatButton: text:'To First Screen' pos_hint:{'center_x':0.3,'center_y':0.3} on_press:root.manager.current='fscr' ''' class Fscr(Screen): pass class Sscr(Screen): pass class MyApp(MDApp): # 定义共享变量,用Kivy属性支持自动绑定更新 shared_text = StringProperty('') def build (self): # 先加载KV得到root实例 root = Builder.load_string(kv) # 现在就可以正常访问组件属性了 df = root.screens[0].ids.inp.text print(df) return root MyApp().run()
变量共享说明
- 在MDApp子类中定义的Kivy属性,在KV中可以直接通过
app.属性名访问和赋值,在Python代码中可以通过MDApp.get_running_app().属性名访问。 - 这种方式天然支持Kivy的绑定机制,属性值变化时所有绑定的组件会自动更新,不需要手动赋值修改其他组件的内容,耦合度低,维护方便。
内容的提问来源于stack exchange,提问作者K V Ramana
相关产品推荐
相关产品推荐

