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

在Kivy中跨类访问对象属性时遇AttributeError错误如何解决?

解决Kivy中跨类访问ids出现的AttributeError: 'super' object has no attribute '__getattr__'错误

嘿,我来帮你搞定这个头疼的Kivy报错!你遇到的这个错误,本质原因是你在当前类里直接用self.ids去访问另一个类的控件属性——但self.ids只能访问当前类(也就是触发按钮所在的Widget/Screen类)内部定义的控件,跨类直接这么用肯定会翻车。

下面我结合常见的两种场景,给你具体的解决方案:

场景1:ScreenManager下的不同Screen之间访问

假设你的代码大概是这样(很多人会踩这个坑):

错误的Python代码

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen

class BoysScreen(Screen):
    def on_boys_button_click(self):
        # 错误:直接尝试访问GirlsScreen的ids
        self.ids.girls_label.text = "来自男孩按钮的问候!"

class GirlsScreen(Screen):
    pass

class MyApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(BoysScreen(name='boys'))
        sm.add_widget(GirlsScreen(name='girls'))
        return sm

if __name__ == '__main__':
    MyApp().run()

对应的KV文件

<BoysScreen>:
    Button:
        text: "Button for boys"
        on_press: root.on_boys_button_click()

<GirlsScreen>:
    Label:
        id: girls_label
        text: "初始文本"

修正方案

你需要先通过App实例获取ScreenManager,再拿到目标Screen的实例,最后访问它的ids:

def on_boys_button_click(self):
    # 获取当前运行的App实例
    current_app = App.get_running_app()
    # 通过ScreenManager获取GirlsScreen的实例
    girls_screen = current_app.root.get_screen('girls')
    # 现在可以正常访问目标控件了
    girls_screen.ids.girls_label.text = "来自男孩按钮的问候!"

场景2:自定义Widget嵌套时跨类访问

如果你的界面是自定义Widget嵌套的结构,比如MainLayout里包含BoysWidget和GirlsWidget:

错误的Python代码

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class GirlsWidget(BoxLayout):
    pass

class BoysWidget(BoxLayout):
    def on_boys_button_click(self):
        # 错误:直接用self.ids访问GirlsWidget的控件
        self.ids.girls_label.text = "按钮被点击啦!"

class MainLayout(BoxLayout):
    pass

class MyApp(App):
    def build(self):
        return MainLayout()

对应的KV文件

<GirlsWidget>:
    Label:
        id: girls_label
        text: "你好呀"

<BoysWidget>:
    Button:
        text: "Button for boys"
        on_press: root.on_boys_button_click()

<MainLayout>:
    GirlsWidget:
        id: girls_widget
    BoysWidget:
        id: boys_widget

修正方案

通过当前Widget的父控件(MainLayout)获取目标Widget实例,再访问其ids:

def on_boys_button_click(self):
    # 获取父布局MainLayout的实例
    main_layout = self.parent
    # 获取GirlsWidget的实例
    girls_widget = main_layout.ids.girls_widget
    # 访问目标控件
    girls_widget.ids.girls_label.text = "按钮被点击啦!"

关键注意点

  • 确保KV文件中目标控件的id拼写正确,没有笔误
  • 不要在类的__init__方法里过早访问ids(此时控件还未初始化完成)
  • 跨类访问的核心是先拿到目标类的实例,再通过实例访问ids,而不是直接用当前类的self.ids

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:29:41