Search code examples
pythonkivy

How to update a kivy ListProperty of root widget from a child widget?


I have the following kivy layout in my app

ABC:

<ABC>:

    BoxLayout:
    orientation: 'vertical'

    Label:
        text: str(root.current_cell)

    GridLayout:
        id: grid
        cols: 10

The contents of the grid layout is dynamically generated in the Python code

class ABC(BoxLayout):
    current_cell = ListProperty([0, 0])
    
    def on_size(self, *args):
        self.draw_grid()

    def draw_grid(self):
        for i in range(10):
            for j in range(10):
                self.ids.grid.add_widget(Cell(cell_id=[i, j]))

Cell widget is a child of TextInput widget

class Cell(TextInput):
    def __init__(self, cell_id, **kwargs):
        super().__init__(**kwargs)
        self.cell_id = cell_id

    def _on_focus(self, instance, value, *largs):
        if value:
            ABC.current_cell = self.cell_id # Issue is here
        return super()._on_focus(instance, value, *largs)

When the user focuses any cell in the grid it should update the ABC.current_cell which in turn will update the label's text in the layout. The above code is not working. I am new to kivy so having hard time understanding what is wrong. Thanks in advance!


Solution

  • Well, first you need to pass a reference from the ABC class to the Cell class and modify it later.

    Small example:

    class ABC(BoxLayout):
        current_cell = ListProperty([0, 0])
        def draw_grid(self):
            add = self.ids.grid.add_widget             
            add(Cell(abc=self, cell_id=[i, j]))
    
    class Cell(TextInput):
        def __init__(self, abc, cell_id):
            self.abc = abc
            self.cell_id = cell_id
    
        def _on_focus(self):
            self.abc.current_cell = self.cell_id