taichi
taichi

Reputation: 683

Using Kivy, dynamically add items when a button is pressed

I wrote the following code. I want to be able to dynamically add as many items as I want when I press the Add Item button.

#-*- coding: utf-8 -*-
from kivy.config import Config
Config.set('graphics', 'width', 300)
Config.set('graphics', 'height', 300)

from kivy.lang import Builder
Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                orientation: 'vertical'

                Button:
                    id: button1
                    text: "Button1"

                Button:
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()
""")

from kivy.app import App
from kivy.uix.widget import Widget

from kivy.properties import StringProperty 

class AddItemWidget(Widget):
    text = StringProperty()

    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)

    def buttonClicked(self):
        print("add item test")

class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

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

How do I get an element to be added when I click on a button, as in the image below?

enter image description here

Instead of just adding one, I want to be able to add 100 or 200 depending on how many times I click the button.

I'd like to be able to delete the buttons I've added as well.

Upvotes: 0

Views: 719

Answers (1)

John Anderson
John Anderson

Reputation: 38947

You can use add_widget() to add new Buttons to your BoxLayout, and using index=1 always adds the new Button just above the Add Item Button. To do that, you need a reference to the BoxLayout, and that can be done by adding an id to it in your kv. Here is a modified version of your code that does that:

#-*- coding: utf-8 -*-
from kivy.config import Config
from kivy.uix.button import Button

Config.set('graphics', 'width', 300)
Config.set('graphics', 'height', 300)
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')  # eliminate annoying circle drawing on right click

from kivy.lang import Builder
Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                id: box
                orientation: 'vertical'

                Button:
                    id: button1
                    text: "Button1"

                Button:
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()
""")

from kivy.app import App
from kivy.uix.widget import Widget

from kivy.properties import StringProperty

class RemovableButton(Button):
    def on_touch_down(self, touch):
        if touch.button == 'right':
            if self.collide_point(touch.x, touch.y):
                self.parent.remove_widget(self)
                return True
        return super(RemovableButton, self).on_touch_down(touch)


class AddItemWidget(Widget):
    text = StringProperty()

    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)
        self.count = 1

    def buttonClicked(self):
        print("add item test")
        self.count += 1
        newButt = RemovableButton(text='Button'+ str(self.count))
        self.ids.box.add_widget(newButt, index=1)


class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

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

I have extended Button in a RemovableButton class and wrote an on_touch_down() method that removes the RemovableButton on a right click. By adding RemovableButtons, the removal is easy. You may want to show a Popup that gives the user a chance to change his/her mind about doing a removal.

Upvotes: 1

Related Questions