You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 09:36:00