'How to add widgets while Kivy app is running?

I state that I am not an expert in Python and I started very recently with Kivy! I would like to know if it is possible, and if it makes sense, to add widgets such as buttons or labels while the app is running. For example a button that each time it is pressed adds a new button to a screen. I don't know if I've been clear enough.



Solution 1:[1]

This example illustrates the process by creating a new Button each time another Button is pressed, you can also delete (remove) the created buttons.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button



class CustomBox(BoxLayout):

    def add_buttons(self, *args):
        """Method for creating new Button."""
        i = len(self.ids.inner_box.children) # Just to distinguish the buttons from one another.
        btn = Button(
            text = f"Button {i+1}",
            size_hint_y = None,
            height = "64dp",
        )
        self.ids.inner_box.add_widget(btn) # Referencing container by its 'id'.



Builder.load_string("""

<CustomBox>:
    orientation: "vertical"
    spacing: dp(2)

    Button:
        size_hint_y: 0.5
        text: "Add Button"
        color: 0, 1, 0, 1
        on_release: root.add_buttons()

    ScrollView: # To see and add all the buttons in progress.
        BoxLayout: # Button's container.
            id: inner_box
            orientation: "vertical"
            spacing: dp(5)
            padding: dp(5)
            size_hint_y: None # Grow vertically.
            height: self.minimum_height # Take as much height as needed.

    Button:
        size_hint_y: 0.5
        text: "Delete Button"
        color: 1, 0, 0, 1
        on_release: inner_box.remove_widget(inner_box.children[0]) if inner_box.children else None # Here '0' means last added widget.

""")



class MainApp(App):
    def build(self):
        return CustomBox()



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

Solution 2:[2]

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

class BeginnerApp(App):
    
    def build(self):
        root = BoxLayout(orientation='vertical')
        self.count = 0
        
        a = root.add_widget(Button(text='add button', on_press=self.add_button))
        
        b = root.add_widget(Button(text='remove button', on_press=self.delete_button))
        
        return root
        
    
    def add_button(self, *args):
        self.count += 1
        self.root.add_widget(Button(text=str(self.count)))
    
    def delete_button(self, *args):
        if self.count > 0:
            self.root.remove_widget(self.root.children[0])
            self.count -= 1
        else:
            pass
        
        

if __name__ == '__main__':
    app = BeginnerApp()
    app.run()

Note 1: when you bind a method, specify its name without brackets. Otherwise, binding does not work normally.

on_press=self.add_button
on_press=self.delete_button

Note 2: to add widgets in layout you can use method "add_widget()".

self.root.add_widget(Button())

For delete widget you can use method "remove_widget()". To delete a widget in layout, you need to specify this widget. This can be done through the "children" method. The last widget in the "children" method is numbered "0". So you can delete the last widget in layout.

self.root.remove_widget(self.root.children[0])

Note 3: When declaring methods, don't forget *args.

def add_button(self, *args):

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ApuCoder
Solution 2