How to dynamically generate Kivy objects
Question: So I figure out how to dynamically add labels to Kivy, but then I realized
that Kivy has a listview module already, and that that would make things
easier. I found this [Python Kivy ListView: How to delete selected
ListItemButton?](http://stackoverflow.com/questions/25981827/python-kivy-
listview-how-to-delete-selected-listitembutton) answer useful in learning
about implementing a listview, but am wondering how I could add a two column
listview that is updated with text from two textboxes. I edited the code in
the example as a proof of concept for what I want to do and what I have so far
is:

    
    
    # main.py
    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.properties import ObjectProperty
    from kivy.uix.listview import ListItemButton
    
    
    class TaskButton(ListItemButton):
        pass
    
    
    class TodoRoot(BoxLayout):
        task_input = ObjectProperty()
        task_list = ObjectProperty()
    
        def add_task(self):
            self.task_list.adapter.data.extend([self.task_input_1.text + " | " + self.task_input_2.text])
            self.task_list._trigger_reset_populate()
    
        def del_task(self, *args):
            if self.task_list.adapter.selection:
                selection = self.task_list.adapter.selection[0].text
                self.task_list.adapter.data.remove(selection)
                self.task_list._trigger_reset_populate()
    
    
    class TodoApp(App):
        def build(self):
            return TodoRoot()
    
    
    if __name__ == '__main__':
        TodoApp().run()
    

and

    
    
    # todo.kv
    #: import main main
    #: import ListAdapter kivy.adapters.listadapter.ListAdapter
    #: import ListItemButton kivy.uix.listview.ListItemButton
    
    TodoRoot:
    
    <TodoRoot>:
        orientation: "vertical"
        task_input_1: task_input_view_1
        task_input_2: task_input_view_1
        task_list: tasks_list_view
    
        BoxLayout:
            size_hint_y: None
            height: "40dp"
    
            TextInput:
                id: task_input_view_1
                size_hint_x: 70
            TextInput:
                id: task_input_view_2
                size_hint_x: 70
            Button:
                text: "Add"
                size_hint_x: 15
                on_press: root.add_task()
            Button:
                text: "Del"
                size_hint_x: 15
                on_press: root.del_task()
        ListView:
            id: tasks_list_view
            adapter:
                ListAdapter(data=[], cls=main.TaskButton)
    

that sort of works, but its a bit clunky and I would like to have the text
from the two text inputs go into separate columns of the listview but each row
can still be selected as a row.


Answer: Not sure if it is exactly what you asked for; if you need something else,
write in comment:

test.kv:

    
    
    #:kivy 1.9.1
    Screen:
    
        GridLayout:
            size_hint_y: .7
            pos_hint: {'y': .3}
            id: labels_grid
            cols: 2
    
            canvas: # visualize grid layout
                Color:
                    rgb: 0.3, 0.5, 0.3
                Rectangle:
                    size: self.size
                    pos: self.pos
    
        GridLayout:
            size_hint_y: .3
            cols: 1
    
            TextInput:
                id: input_1
    
            TextInput:
                id: input_2
    
            MyButton:
                text: 'add labels to grid'
                text_1: input_1.text # binding labels text for easy use
                text_2: input_2.text # with self.
                on_press: self.add_labels(labels_grid)
    

main.py:

    
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.label import Label
    
    
    class MyButton(Button):
        def add_labels(self, grid_handle):
            text_1 = self.text_1
            text_2 = self.text_2
            label_1 = Label(text=text_1)
            label_2 = Label(text=text_2)
            grid_handle.add_widget(label_1)
            grid_handle.add_widget(label_2)
    
    
    class Test(App):
        pass
    
    
    Test().run()
    

