Search code examples
pythonpython-3.xkivykivymd

How to combine kivy file and loops in python files?


I'm learning how to use kivy. And to get things a little more difficult, I'm using kivyMD to use themes.

I'm trying to simply create a layout in a kivy file and fill it with a python loop in the python file.

My python file, for example :


from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import MDScreen

KV="""
MyWidget:
    MDBoxLayout:
        orientation: 'vertical'

        MDLabel:
            text:"hello world !"
            halign: 'center'

        MDGridLayout:
            id: _grid
            col: 2
        
        MDLabel:
            text:"hello world !"
            halign: 'center'
"""

class MyWidget(MDScreen):
    def on_grid(self):
        for i in range(6):
            self.ids._grid.add_widget(MDLabel(text=str(i+1)))
    pass

#Déclaration du moteur d'application
class MainApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

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

But the GridLayout stays empty.

I really search and tried other solutions with ObjectProperty() but I got even more errors. And I was unable to find a simple example, something less specific and more academic.

What is the best way to create an empty nested widget in a kv file and then fill it with a python loop at launch ?

Thank you for your help.


Solution

  • After a lot of researchs, I found a solution. I hope it will help someone. '''

    from kivy.app import App 
    from kivy.uix.label import Label
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.properties import ObjectProperty
    from kivy.lang import Builder
    
    KV="""
    <MainScreen>:
        grid: _grid
        BoxLayout:  
            Label:
                text: "Hello 1 !"
            GridLayout:
                id: _grid
                cols:2
            Label:
                text: "Hello 2 !"
    """
    
    Builder.load_string(KV)
    
    class MainScreen(Screen):
        grid = ObjectProperty()
    
        def __init__(self, **kwargs):
            super(MainScreen, self).__init__(**kwargs)
            for i in range(6):
                self.grid.add_widget(Label(text=str(i)))
        
    class MyApp(App):
        def build(self):
            return MainScreen()
    
    if __name__ == '__main__':
        MyApp().run()