2

I have a kivy screen that I need to create elements in via a loop. I can do it as so:

class HomeScreen(Screen):

    def show_tasks(self):
        global user

        tasks = DB.get_tasks(user) # Returns an array of tuples
        for task in tasks:
            self.add_widget(Label(text=task[1]))

However, when I do it this way, the labels overlap on top of each other - literally on the z axis, making them all unreadable. Instead I want them to populate one above the other (on the y axis). Not only that, but eventually I'm going to want to create a table-like structure out of the data.

Here's my kv:

<HomeScreen>:
    name: 'home'    
    FloatLayout:
        BoxLayout:
            orientation: "horizontal"
            pos_hint: {"x": 0, "y": 0}
            GridLayout:
                id: grid
                rows: 4
                cols: 1
                padding: 10
                spacing: 10
                row_force_default: True
                row_default_height: 40
                Label:
                    text: 'Your Tasks:'
                    size_hint_x: None
                    width: 200
                    font_size: 24

Any help or insight into how I can solve this problem would be greatly appreciated!

clines
  • 725
  • 1
  • 6
  • 10

1 Answers1

2

In the following code:

self.add_widget(Label(text=task[1]))

self refers to an instance of HomeScreen class so you are adding a child to HomeScreen, not to GridLayout, that is, it is equivalent to:

<HomeScreen>:
    name: 'home' 
    FloatLayout:
        ...
    Label:
        ...
    Label:
        ...

The solution is to add to the GridLayout to do this to grid a property of the class:

<HomeScreen>:
    name: 'home'
    grid: grid    # <---
    FloatLayout:
        BoxLayout:
            orientation: "horizontal"
            pos_hint: {"x": 0, "y": 0}
            GridLayout:
                id: grid
                # rows: 4
                cols: 1
                padding: 10
                spacing: 10
                row_force_default: True
                row_default_height: 40
                Label:
                    text: 'Your Tasks:'
                    size_hint_x: None
                    width: 200
                    font_size: 24

and then we add it using grid in the python part:

class HomeScreen(Screen):
    def show_tasks(self):
        global user
        tasks = DB.get_tasks(user) # Returns an array of tuples
        for task in tasks:
            self.grid.add_widget(Label(text=task[1])) # <---
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • That certainly answered my original question! – clines Jul 10 '18 at 23:49
  • @user2283234 remove `rows: 4` – eyllanesc Jul 10 '18 at 23:51
  • @user2283234 when you set rows = 4 and cols = 1 you are indicating that you will only have rows * cols widgets, in your case only 4, if you do not set rows then it will be assumed that it is undefined. – eyllanesc Jul 10 '18 at 23:53
  • I just saw that you'd commented that out, and tested it and it worked. I seem to be particularly dense today. Thank you so much for the answer though! – clines Jul 10 '18 at 23:56