2

Thanks for taking a look. I'm brand new to Kivy/KivyMD/programming and there's something fundamental I'm just not grasping between the python code and the kv code.

I'm building a simple app that uses ScreenManager to switch between two screens. On each screen, I plan to have a dynamically generated list with data from a database.

I can add static lists and other widgets by putting them in the kv file. But I can't seem to understand how to create/update data in the class in the python file and have it link to the kv file ID.

In the following code, the program works and I've thrown a button in there that successfully generates a list, but the goal is to have no button and have the list generate automatically when the app starts.

I've added some comments with things I've tried. Am I using the wrong variable names or doing something fundamentally wrong?

[main.py python file]

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.list import OneLineListItem


class FirstWindow(Screen):
    print('This prints automatically when App launches')

    # But adding widgets doesn't happen automatically
    # I tried variations but the variable is always not defined
    #self.ids.list_one.add_widget(OneLineListItem(text='List Item 1'))
    #root.ids.list_one.add_widget(OneLineListItem(text='List Item 1'))
    #ids.list_one.add_widget(OneLineListItem(text='List Item 1'))

    # This function works when called from a button
    def button_push(self):
        for i in range (20):
            self.ids.list_one.add_widget(OneLineListItem(text=f'List Item {i}'))

class SecondWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class MultiscreenApp(MDApp):
    def build(self):
        return Builder.load_file('Multiscreen.kv')

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

[Multiscreen.kv file]

WindowManager:
    FirstWindow:
        name: 'firstwindow'
    SecondWindow:
        name: 'secondwindow'


<FirstWindow>:
    BoxLayout:
        orientation: 'vertical'

        MDToolbar:
            title: 'SCREEN 1'

        Button:
            text: 'List maker button'
            on_release: root.button_push()

        ScrollView:
            MDList:
                id: list_one

        MDFloatingActionButton:
            elevation: 8
            icon: 'plus'
            pos_hint: {'center_x': .5}
            on_press:
                app.root.current = 'secondwindow'
                root.manager.transition.direction = 'left'

<SecondWindow>:
    BoxLayout:
        orientation: 'vertical'

        MDToolbar:
            title: 'SCREEN 2'

        ScrollView:
            MDList:
                id: list_two

        MDRaisedButton:
            text: 'Go Back'
            on_release:
                app.root.current = 'firstwindow'
                root.manager.transition.direction = 'right'
DanHeatWave
  • 23
  • 1
  • 4

2 Answers2

2

You can add __init___ method with Clock.schedule_once to trigger the list creation. Modified code is below. I haven't changed the rest of the code, just added two functions to show automatic list creation.

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.list import OneLineListItem
from kivy.clock import Clock

class FirstWindow(Screen):
    print('This prints automatically when App launches')
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_once(self.create_list)
        
    def create_list(self, *args):
        for i in range (20):
            self.ids.list_one.add_widget(OneLineListItem(text=f'List Item {i}'))
    # But adding widgets doesn't happen automatically
    # I tried variations but the variable is always not defined
    #self.ids.list_one.add_widget(OneLineListItem(text='List Item 1'))
    #root.ids.list_one.add_widget(OneLineListItem(text='List Item 1'))
    #ids.list_one.add_widget(OneLineListItem(text='List Item 1'))

    # This function works when called from a button
    def button_push(self):
        for i in range (20):
            self.ids.list_one.add_widget(OneLineListItem(text=f'List Item {i}'))

class SecondWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class MultiscreenApp(MDApp):
    def build(self):
        return Builder.load_file('Multiscreen.kv')

if __name__ == '__main__':
    MultiscreenApp().run()
amras
  • 1,499
  • 2
  • 6
  • 10
1
class FirstWindow(Screen):
    def on_enter(self, *args):
        """Event fired when the screen is displayed: the entering animation is
        complete."""

        def on_enter(interval):
            for i in range (20):
                self.ids.list_one.add_widget(OneLineListItem(text=f'List Item {i}'))

        Clock.schedule_once(on_enter)
Xyanight
  • 1,315
  • 1
  • 7
  • 10