pythonwidgetkivyscreens

Kivy widget in python to kv file, how control it


i have a simple test program:

main.py

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen
from kivy.clock import mainthread


class TestScreen(Screen):
@mainthread
def on_pre_enter(self): #Is loaded before kv buttons etc? how make it work
   pass
@mainthread
def on_enter(self): #Load after kv buttons etc?
    button = Button(text="Work?")
    #how now add it to display?
    #how control where display it? on end or begin is just about on_pre and on?

class TestApp(App):
    pass

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

And test.kv file

#:import NoTransition kivy.uix.screenmanager.NoTransition 
<TestScreen>:   
    name:'try'
    GridLayout:
        id:'test'
        cols:2
        Button:
            text:'Test'
            on_press:app.root.current='Main'
ScreenManager:
    transition: NoTransition()
    Screen:
        name: 'Main'
        GridLayout:
            cols:1
            Button:
                text:'1'                
            Button:
                text:'2'
            Button:
                text:'Test'
                on_press:root.current='try'
    TestScreen:

Is simple to control kv and python widgets(but i dont know how but is more easy to writes widgets etc in kv file, but still need create some in python for automatic content) or better just create all in python withou kv file? I wanna make somehting like this: App with left menu always displayed and on the right side another screen with dynamic content based on screen(clicked from menu) is maybe another simple solution for this. Anyone can explain me step by step? :)


Solution

  • AttributeError

    The solution to AttributeError, please replace "id: 'test'" with "id: test" in test.kv file.

    Dynamic Content

    It is possible to display screen with dynamic content based on clicked from menu. But remember to remove the widgets that were added when exiting the screen (TestScreen/SettingsScreen). If you do not remove the widgets, you will get duplicates/multiples of each widget added each time you enter the screen (TestScreen/SettingsScreen). I recommend using on_pre_enter and on_leave methods. Please refer to the example below for details.

    Example

    main.py

    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.uix.button import Button
    
    
    class MyScreenManager(ScreenManager):
        pass
    
    
    class MenuScreen(Screen):
        pass
    
    
    class SettingsScreen(Screen):
        def on_pre_enter(self, *args):
            self.ids.test.add_widget(Button(text="Work?"))
    
        def on_leave(self, *args):
            self.ids.test.remove_widget(self.ids.test.children[0])
    
    
    class TestApp(App):
        title = "Add & Remove Widgets Dynamically"
    
        def build(self):
            return MyScreenManager()
    
    
    if __name__ == "__main__":
        TestApp().run()
    

    test.kv

    #:kivy 1.10.0
    #:import NoTransition kivy.uix.screenmanager.NoTransition
    
    <MyScreenManager>:
        transition: NoTransition()
        MenuScreen:
        SettingsScreen:
    
    <MenuScreen>:
        name: 'menu'
        GridLayout:
            cols: 1
            Button:
                text: '1'
            Button:
                text: '2'
            Button:
                text: 'Test'
                on_press: root.manager.current = 'settings'
    
    <SettingsScreen>:
        name:'settings'
        GridLayout:
            id: test
            cols: 2
            Button:
                text: 'Test'
                on_press: root.manager.current = 'menu'
    

    Output

    enter image description here