Search code examples
pythonclasskivykivy-language

How to add Widgets from outside class with Kivy


Hy! I have this app here, a kind of "To Do List". When I press "Add Item" Button, it opens a PopUp Window and I want when "Up" Button is pressed to add "ItemTemplate" in "ItemsList". I am new in Kivy and I tried do that in last few days. How can I do that?
Thanks a lot!

Python code:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup

class FirstBox(BoxLayout):
    def btn(self):
        Pu().open()

class ItemsList(GridLayout):
    pass

class ItemTemplate(BoxLayout):
    pass

class Pu(Popup):
    pass

class MyAppApp(App):
    pass

MyAppApp().run()

Kv code:

FirstBox:
<FirstBox>:
    orientation: "vertical"
    BoxLayout:
        ScrollView:
            ItemsList:
                size_hint: 1, None
                height: self.minimum_height

    Button:
        size_hint: 1,0.2
        text: "Add Item"
        on_release: root.btn()
<ItemsList>:
    cols: 1
    size_hint_y: None
    ItemTemplate:
    ItemTemplate:
    ItemTemplate:
<ItemTemplate>:
    size_hint: 1, None
    CheckBox:
        size_hint: 0.15, 1
    Button:
        text: "Task Name"
    Button:
        text: "Some action"
        size_hint: 0.15,1
<Pu>:
    size_hint: 1, 0.3
    BoxLayout:
        orientation: "vertical"
        TextInput:
        Button:
            text: "Up"

Solution

  • Give id to your ItemList for add widget and TextInput for get text from.

    ItemsList:
        id: viewlist
    

    and

    TextInput:
        id: new_task_input_id
    

    Use StringProperty for dinamicly change text of ItemTemplate:

    from kivy.properties import StringProperty
    class ItemTemplate(BoxLayout):
        task_text = StringProperty()
    

    Edit .kv side dinamic: ( ItemTemplate's Button )

    Button:
        text: root.task_text
    

    Trigger Up Button in .kv side: on_release: root.add_item() Create this function in Pu class and add this operations:

    def add_item(self,*args):
        firstbox = App.get_running_app().root #access correctly main layout
        itemlist = firstbox.ids.viewlist #find viewlist by id
        new_task_text = self.ids.new_task_input_id.text  #get textinput text
        item = ItemTemplate()  #create custom item
        item.task_text = new_task_text  #set item text
        itemlist.add_widget(item) #add item to layout
        
    

    Short function:

    App.get_running_app().root.ids.viewlist.add_widget(ItemTemplate(task_text=self.ids.new_task_input_id.text))
    

    Lets close popup after add new item:

    self.dismiss()
    

    Also if you want to add this widget to top, need to give index in add_widget :

    itemlist.add_widget(item,len(itemlist.children))