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

KivyMD出现AttributeError报错:'super'对象无'__getattr__'属性求助

错误原因分析
  1. IDS获取路径错误:根控件ScreenManager的ids集合中不存在tool1,tool1是嵌套在HomePage、SecondPage内部的MDTopAppBar控件ID,根控件无法直接访问子Screen内部的控件ID。
  2. 初始化时机过早:在__init__方法中创建MDDropdownMenu时,KV文件加载的控件树还未完成初始化,此时尝试获取caller会触发属性错误。
  3. KV语法错误:right_action_items的格式错误,正确格式应为[['图标名称', 回调函数]],原代码中将图标和回调拆成了两个列表元素,导致逻辑失效。
  4. Build方法冗余:在build中创建了新的ScreenManager但未使用,直接返回预加载的self.screen,逻辑混乱。
修正后的实现方案

1. 调整菜单创建时机

将MDDropdownMenu的创建移至on_start方法,此时所有控件已完成初始化,可正确获取目标控件。

2. 正确获取Caller

通过当前活动Screen获取内部的tool1控件,后续菜单弹出时会自动适配点击的工具栏控件。

3. 修复KV语法错误

修正right_action_items的格式,确保图标和回调在同一个列表元素中。

4. 清理冗余代码

移除build方法中未使用的ScreenManager创建代码。


修正后的Python代码

from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.menu import MDDropdownMenu
from kivy.metrics import dp
from kivy.core.window import Window

Window.size = (500, 800)

class HomePage():
    pass

class SecondPage():
    pass

class App(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_file("kivy.kv")
        self.menu = None

    def on_start(self):
        # 初始化下拉菜单,此时控件已全部加载完成
        items_d = ['Settings', 'Profile', 'Log Out', 'Exit']
        menu_items = [
            {
                "text": f"{i}",
                "viewclass": "OneLineListItem",
                "height": dp(40),
                "on_release": lambda x=f"{i}": self.menu_callback(x),
            } for i in items_d
        ]
        # 获取初始页面的工具栏作为菜单默认调用者
        self.menu = MDDropdownMenu(
            caller=self.screen.get_screen('first').ids.tool1,
            items=menu_items,
            width_mult=2
        )

    def menu_callback(self, text_item):
        print(text_item)
        self.menu.dismiss()

    def build(self):
        self.theme_cls.primary_palette = 'Red'
        self.theme_cls.primary_hue = '500'
        self.theme_cls.theme_style = 'Dark'
        return self.screen

App().run()

修正后的KV文件

#:kivy 2.1.0

ScreenManager:
    HomePage:
    SecondPage:

<HomePage@Screen>
    name: 'first'

    MDNavigationLayout:
        ScreenManager:
            Screen:
                BoxLayout:
                    orientation:'vertical'

                    MDTopAppBar:
                        id:tool1
                        title: 'Home Page'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state('toggle')]]
                        # 修复right_action_items格式:图标和回调在同一个列表内
                        right_action_items: [['dots-vertical', lambda x: app.menu.open()]]
                        elevation: 3

                    MDLabel:
                        text: "Home Page Content"

                    MDBottomAppBar:
                        MDTopAppBar:
                            icon: 'apps'
                            mode: 'center'
                            type: 'bottom'

        MDNavigationDrawer:
            id: nav_drawer

            ScrollView:
                MDList:
                    OneLineIconListItem:
                        text: 'Home Page'
                        on_press: 
                            nav_drawer.set_state('close')
                            root.manager.current = 'first'

                        IconLeftWidgetWithoutTouch:
                            icon:'bluetooth'

                    OneLineIconListItem:
                        text: 'Content Page'
                        on_press: 
                            root.manager.current = 'second'
                            nav_drawer.set_state('close')
                                
                        IconLeftWidgetWithoutTouch:
                            icon:'content-copy'


<SecondPage@Screen>
    name: 'second'

    MDNavigationLayout:
        ScreenManager:
            Screen:
                BoxLayout:
                    orientation:'vertical'

                    MDTopAppBar:
                        id:tool1
                        title: 'Content Page'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state('toggle')]]
                        right_action_items: [['dots-vertical', lambda x: app.menu.open()]]
                        elevation: 3

                    MDLabel:
                        text: "Second Page Content"

                    MDBottomAppBar:
                        MDTopAppBar:
                            type: 'bottom'
                            icon: 'apps'
                            mode: 'center'
                            left_action_items: [['information']]

        MDNavigationDrawer:
            id: nav_drawer

            ScrollView:
                MDList:
                    OneLineIconListItem:
                        text: 'Home Page'
                        on_press: 
                            nav_drawer.set_state('close')
                            root.manager.current = 'first'

                        IconLeftWidgetWithoutTouch:
                            icon:'bluetooth'

                    OneLineIconListItem:
                        text: 'Second Page'
                        on_press: 
                            nav_drawer.set_state('close')
                            root.manager.current = 'second'

                        IconLeftWidgetWithoutTouch:
                            icon:'wifi'

内容的提问来源于stack exchange,提问作者meelioo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:35:39