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

Python Kivy跨类调用函数报错:AttributeError: 'Test'无'User'属性

解决AttributeError:调用User类calculate方法的正确方式

你遇到的AttributeError: 'Test' object has no attribute 'User',本质原因是你在尝试访问App.get_running_app().User时,User并不是Test应用实例的属性——你只是定义了User这个Popup类,但并没有在App或合适的位置保存它的实例引用。下面提供两种可靠的解决方法:

方法一:通过实例传递(推荐,耦合度更低)

这种方法是把User弹窗的实例直接传递给每个Row,让Row能直接调用它的calculate方法:

  1. 修改Row类,添加一个user属性来保存User实例,并在on_text方法中调用该实例的calculate:
class Row(BoxLayout):
    col_data = ListProperty(["?", "?", "?", "?", "?"])
    button_text = StringProperty("")
    col_data3 = StringProperty("")
    col_data4 = StringProperty("")
    user = ObjectProperty(None)  # 新增:存储User实例

    def __init__(self, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.ids.number_input.bind(text=self.on_text)

    def on_text(self, text_input, value):
        print('Calling')
        if self.user:  # 确保实例存在再调用
            self.user.calculate()
  1. 修改Rows类,让它接收User实例,并在创建Row时传递过去:
class Rows(BoxLayout):
    row_count = 0
    def __init__(self, **kwargs):
        self.user = kwargs.pop('user', None)  # 接收User实例
        super(Rows, self).__init__(**kwargs)
        self.add_row()

    def add_row(self):
        self.row_count += 1
        # 创建Row时把User实例传进去
        self.add_widget(Row(button_text=str(self.row_count), user=self.user))
  1. 修改demo.kv中的User布局,给Rows传递当前User实例:
<User>:
    id: user
    total_value:total_value
    BoxLayout:
        orientation: "vertical"
        padding : 20, 5
        # ... 其他原有代码 ...
        ScrollView:
            Rows:
                id: rows
                user: root  # 把当前User实例传给Rows

这样,每个Row都能拿到对应的User弹窗实例,输入文本时就能正确触发calculate方法了。

方法二:将User实例存储到App属性中

如果你不想修改太多布局传递逻辑,也可以把User实例存到App的属性里,让Row直接从App获取:

  1. 修改rv类的add方法,创建User弹窗时把它赋值给App的属性:
class rv(BoxLayout):
    data_items = ListProperty([])
    mode = StringProperty("")
    def __init__(self, **kwargs):
        super(rv, self).__init__(**kwargs)
    def add(self):
        self.mode = "Add"
        popup = User()
        App.get_running_app().user_popup = popup  # 把弹窗实例存到App
        popup.open()
  1. 修改Row类的on_text方法,从App中获取实例并调用calculate:
def on_text(self, text_input, value):
    print('Calling')
    app = App.get_running_app()
    # 检查属性存在且实例有效
    if hasattr(app, 'user_popup') and app.user_popup:
        app.user_popup.calculate()

这种方法更简单,但要注意如果同时打开多个User弹窗,后面的会覆盖前面的实例,适合单弹窗场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:50:18