Search code examples
pythonkivy

Empty list of ids in a Kivy GridLayout


I am trying to develop a toy app with Kivy.

So far I have a grid of 9 x 9 TextInput widgets that have been added programmatically to a GridLayout (I refer to it by the id "grid" in my kv file).

For some reason, although I am assigning an id to each of the TextInput widgets, the ids dictionary that I get in the get_widget_from_id is empty.

What am I missing?

main.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.clock import Clock

class SudokuGame(Widget):
    # Initialize the grid of text inputs
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        grid = self.ids["grid"]
        for i in range(81):
            row = i // 9
            col = i  % 9
            grid.add_widget(TextInput(id = str(row) + "-" + str(col)))

    # Try to retrieve one of the widgets from its id
    def get_widget_from_id(self, *args):
        print(self.ids["grid"].ids)

class SudokuApp(App):
    def build(self):
        game = SudokuGame()
        Clock.schedule_once(game.get_widget_from_id)
        return game

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

sudoku.kv

#:kivy 1.9.1

<TextInput@SudokuGame>:
    text: ""
    font_size: 0.7 * self.width
    padding: 0.3 * self.width, (self.height - self.line_height) / 2
    input_filter: lambda text, from_undo: text if ( 0 < int(text) < 10 and len(self.text) == 0 ) else ""
    multiline: False
    cursor_color: [0, 0, 0, 0]

<SudokuGame>:
    canvas.before:
        Color:
            rgb: 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size
    BoxLayout:
        orientation: "vertical"
        size: root.size
        GridLayout:
            id: grid
            rows: 9
            cols: 9
            line_size: 6
            canvas:
                Color:
                    rgb: 0, 0, 0
                Rectangle:
                    pos: self.x + self.width / 3 - self.line_size / 2, self.y
                    size: self.line_size, self.height
                Rectangle:
                    pos: self.x + 2 * self.width / 3 - self.line_size / 2, self.y
                    size: self.line_size, self.height
                Rectangle:
                    pos: self.x, self.y  + self.height / 3 - self.line_size / 2
                    size: self.width, self.line_size
                Rectangle:
                    pos: self.x, self.y  + 2 * self.height / 3 - self.line_size / 2
                    size: self.width, self.line_size
        BoxLayout:
            orientation: "horizontal"
            size_hint: 1, 0.1
            Button:
                text: "Solve"
            Button:
                text: "Clear"

Solution

  • The ids dict is populated only from kv ids. The Kivy property that widgets have is actually unrelated, and I'm not sure if it's used for anything.