Search code examples
pythonpython-3.xkivywidgetkivy-language

Dynamic ID (Kivy)


Sorry for the English mistakes, but I'm using Google translator to try to communicate, because I didn't find any solution in the forum where I live.

I've searched everywhere and I understand that there's no way to put an id on a dynamically added widget. But then how do I get some information, for example, from a dynamically added textinput?

Please help me, because I'm already getting desperate with the same problem for a week.

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

class MeuLayout(ScrollView):
    def criar_pessoa(self, numero):
        if numero.isnumeric():
            if int(numero) > 20:
                pyautogui.alert('Excedeu o valor limite!')
            else:
                i=1
                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))
                    self.ids.grid.add_widget(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))
                    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))
                    self.ids.grid.add_widget(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))
                    self.ids.grid.add_widget(Label(text='___________________________________________________________', size_hint_y=None, height=100))
                    self.ids.grid.add_widget(Label(text='___________________________________________________________', size_hint_y=None, height=100))

                    i+=1

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

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()

Kv code:

<MeuLayout>
    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

Solution

  • There is 2 way to access widgets dynamically which are created in python side:

    First way:

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

    For get these widgets text:

    print(a.text) #in same function
    

    If you need to access these widgets from another class, you need to use App.get_running_app().

    Second way:

    Accessing parent widget and return its children:

    print(self.ids.grid.children)
    

    It returns list of children and you can pick'em by one by. But in here , you need to search'em for find which one you want to access. For that, you can use isinstance or checking their text or other properties.