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

Kivy通过App.get_running_app().root访问方法内变量报错排查

报错根因

你遇到的AttributeError: 'function' object has no attribute 'nome'由两个核心问题导致:

  • 变量作用域不合法:nome/sobrenome/email/telefone是定义在criar_pessoa方法内部的局部变量,仅在该方法执行过程中有效,方法运行结束后就会被回收,外部无法访问。你写的App.get_running_app().root.criar_pessoa.nome本质是试图给criar_pessoa这个函数对象读取不存在的属性,不符合Python语法规则。
  • 隐藏逻辑bug:你创建邮箱、手机号输入框时,添加到布局中的是新生成的匿名TextInput控件,并非你存入列表的email_pessoa、telefone_pessoa实例,后续就算能正常访问列表,拿到的也不是用户实际输入内容的控件。
修复步骤
  1. 将存储动态输入控件的列表改为MeuLayout类的实例属性,用self.前缀定义,保证类内所有方法都可以访问。
  2. 修正邮箱、手机号输入框的添加逻辑,将存入列表的控件实例添加到布局中,不要新建匿名控件。
  3. 提交按钮的触发方法中,直接通过self访问存储控件的实例属性即可,无需通过App.get_running_app()绕路获取根控件。
修复后核心代码
class MeuLayout(ScrollView):
    def criar_pessoa(self, numero):
        if numero.isnumeric():
            if int(numero) > 20:
                pyautogui.alert('Excedeu o valor limite!')
            else:
                i=1
                # 原局部变量改为类实例属性
                self.nome = []
                self.sobrenome = []
                self.email = []
                self.telefone = []
                while i < int(numero)+1:
                    self.ids.grid.add_widget(Label(text= f'Nome da {i}° pessoa:', size_hint_y= None, height= 100))
                    self.ids.grid.add_widget(Label(text=f'Sobrenome da {i}° pessoa:', size_hint_y=None, height=100))

                    nome_pessoa = TextInput(write_tab= False, multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(nome_pessoa)
                    self.nome.append(nome_pessoa)

                    sobrenome_pessoa = TextInput(write_tab= False, multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(sobrenome_pessoa)
                    self.sobrenome.append(sobrenome_pessoa)

                    self.ids.grid.add_widget(Label(text=f'Email da {i}° pessoa:', size_hint_y=None, height=100))
                    self.ids.grid.add_widget(Label(text=f'Telefone da {i}° pessoa:', size_hint_y=None, height=100))

                    email_pessoa = TextInput(write_tab= False, multiline=False, size_hint_y=None, height=30)
                    # 修复:添加存入列表的控件实例,不要新建匿名控件
                    self.ids.grid.add_widget(email_pessoa)
                    self.email.append(email_pessoa)

                    telefone_pessoa = TextInput(write_tab= False, multiline=False, size_hint_y=None, height=30)
                    # 修复:添加存入列表的控件实例,不要新建匿名控件
                    self.ids.grid.add_widget(telefone_pessoa)
                    self.telefone.append(telefone_pessoa)

                    i += 1
                    if i - 1 != int(numero):
                        self.ids.grid.add_widget(Label(text='_'*60, size_hint_y=None, height=100))
                        self.ids.grid.add_widget(Label(text='_'*60, size_hint_y=None, height=100))

                    if i-1 == int(numero):
                        self.ids.grid.add_widget(Label(text='', size_hint_y=None, height=100))
                        botao = Button(text='Iniciar', size_hint_y= None, height= 50, on_release = self.enviar)
                        self.ids.grid.add_widget(botao)

        else:
            pyautogui.alert('Coloque apenas números!')
        self.ids.numero_pessoas.text = ''

    def enviar(self, widget):
        # 直接通过self访问实例上存储的控件列表
        if self.nome:
            n = self.nome[0].text
            print(n)
            # 遍历四个列表即可拿到所有用户输入的姓名、姓氏、邮箱、手机号

优化建议:如果需要支持重复触发生成控件的逻辑,可以把动态生成的控件单独放在一个子GridLayout容器中,清空时只清空这个子容器即可,避免误删kv里定义的固定输入项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:31:18