KivyMD调用get_id获取root.ids返回空字典问题求解
代码说明
我有两个ScreenList对象的id(proof_list和menu_list)。当我点击列表项instance_item时,需要获取其关联父组件的id,check_id函数预期通过调用get_id(instance_item.parent)打印父组件的id,结果应为proof_list或menu_list二者之一。
问题描述
get_id方法无法获取到完整的self.root.ids字典,打印结果为空字典。我尝试在on_start方法中打印self.root.ids,可正常输出完整的id字典。我需要在get_id方法中访问self.root.ids,判断传入实例是否在该id字典中,存在则返回对应的id。
咨询问题
- 为什么on_start方法中可以获取到完整的id字典?
- 如何让get_id方法和on_start方法一样获取到完整的id字典?
复现代码
from kivymd.app import MDApp from kivymd.theming import ThemableBehavior from kivy.lang import Builder from kivymd.uix.list import MDList, OneLineListItem from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty proof_helper = """ Screen: MDNavigationLayout: ScreenManager: id: screen_manager Screen: name: 'menu' BoxLayout: orientation: 'vertical' MDToolbar: title: "Menu Screen" elevation: 8 ScrollView: ScreenList: id: menu_list screen_manager:screen_manager OneLineListItem: text: "Some Item" on_release: self.parent.check_id(self) Screen: name: 'screen2' BoxLayout: orientation: 'vertical' MDToolbar: title: "Proofs" elevation: 8 ScrollView: ScreenList: id: proof_list screen_manager:screen_manager OneLineListItem: text: "Another Item" on_release: self.parent.check_id(self) """ class ScreenList(ThemableBehavior, MDList): screen_manager = ObjectProperty() def check_id(self, instance_item): e1 = ProofApp() parent_id = e1.get_id(instance_item.parent) print(parent_id) class ProofApp(MDApp): def build(self): screen = Builder.load_string(proof_helper) return screen def on_start(self): print(self.root.ids) def get_id(self, instance_item): for id, widget in self.root.ids.items(): if instance_item == widget: print(self.root.ids) return str(id) print(self.root.ids) return "" ProofApp().run()
问题解答
为什么on_start方法可以获取完整id字典
Kivy有固定的App生命周期:执行build方法加载kv布局时,会解析所有组件的id属性,等布局完全加载、所有组件实例化完成后,才会触发on_start回调。此时根节点的ids字典已经完成填充,所以可以正常输出完整的id内容。
如何让get_id方法获取完整id字典
你当前的问题根因是在check_id方法里错误地新建了一个ProofApp实例:这个新实例没有执行run方法,也没有加载布局,它的root属性对应的布局根本没有完成id解析,所以ids字典为空。
你需要调用当前正在运行的App实例的get_id方法,修改ScreenList类的check_id方法即可:
class ScreenList(ThemableBehavior, MDList): screen_manager = ObjectProperty() def check_id(self, instance_item): # 获取当前运行的App实例,不要新建实例 e1 = MDApp.get_running_app() parent_id = e1.get_id(instance_item.parent) print(parent_id)
修改后点击列表项即可正常打印出对应的父组件id:menu_list或proof_list。
内容的提问来源于stack exchange,提问作者Tech320
相关产品推荐
相关产品推荐

