Home > Mobile >  Access a variable inside a method through App.get_running_app().root (Kivy)
Access a variable inside a method through App.get_running_app().root (Kivy)

Time:06-24

I'm trying to access variables that are inside another method. However, I am getting an error.

I'm creating TextInput, according to the number the user passes, and then when the user fills in that TextInput, I want to take the text written by the user and use it for a specific purpose after the button is pressed. I'm trying to do this through App.get_running_app().root.something

Python code:

import sys, os, pyautogui
from kivy.app import App
from kivy.resources import resource_add_path
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

class MeuLayout(ScrollView):
    def criar_pessoa(self, numero):
        if numero.isnumeric():
            if int(numero) > 20:
                pyautogui.alert('Excedeu o valor limite!')
            else:
                i=1
                nome = []
                sobrenome = []
                email = []
                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)
                    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)
                    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(TextInput(write_tab= False,multiline=False, size_hint_y=None, height=30))
                    email.append(email_pessoa)

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

                    i  = 1
                    if i - 1 == int(numero):
                        pass
                    else:
                        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):
        n = App.get_running_app().root.criar_pessoa.nome[0].text
        print(n)

class AppCadastro(App):
    def build(self):
        return MeuLayout()


if __name__ == '__main__':
    if hasattr(sys, '_MEIPASS'):
        resource_add_path(os.path.join(sys._MEIPASS))
    AppCadastro().run()

Kivy code:

<MeuLayout>
    scroll_wheel_distance:80
    GridLayout:
        cols: 2
        id: grid
        size_hint_y: None
        height: self.minimum_height

        Label:
            text: 'Seu email:'
            font_size: 17
            size_hint_y: None
            height: 100
        AnchorLayout:
            anchor_x: 'left'
            anchor_y: 'center'
            TextInput:
                id: email
                write_tab: False
                multiline: False
                size_hint_x: None
                width: 300
                size_hint_y: None
                height: 30

        Label:
            text: 'Sua senha:'
            font_size: 18
            size_hint_y: None
            height: 100
        AnchorLayout:
            anchor_x: 'left'
            anchor_y: 'center'
            TextInput:
                id: senha
                write_tab: False
                multiline: False
                password: True
                size_hint_x: None
                width: 300
                size_hint_y: None
                height: 30



        Label:
            text : 'Quantidade de pessoas: (limite: 20)'
            font_size: 18
            size_hint_y: None
            height: 100
        AnchorLayout:
            anchor_x: 'left'
            TextInput:
                id: numero_pessoas
                write_tab: False
                multiline: False
                size_hint: .1, .1
                size_hint: None, None
                height: 30
                width: 30
                on_text_validate: root.criar_pessoa(numero_pessoas.text)

        Label:
            size_hint_y: None
            height: 100
        Label:
            size_hint_y: None
            height: 100

Error: AttributeError: 'function' object has no attribute 'nome'

CodePudding user response:

You cannot access a variable like nome in your criar_pessoa() method because it is a local variable (local to that method) and is discarded as soon as the method completes. If you want to access nome, you need to change it into a type of variable that will be maintained after the method completes. One way to do this is to make it and instance variable of the MeuLayout class. Simply change every occurrence of the nome variable to self.nome, them replace:

def enviar(self, widget):
    n = App.get_running_app().root.criar_pessoa.nome[0].text
    print(n)

with:

def enviar(self, widget):
    n = App.get_running_app().root.nome[0].text
    print(n)
  • Related