Search code examples
pythonpython-3.xkivy

Accessing Python/Kivy dynamic screen class


So I've been working on an application that uses multiple screens, one of which is a settings screen with a theme chooser. The code looks something like this:

Python:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

class MainScreen(Screen):
    pass

class SettingsScreen(Screen):
     
    def changeTheme(self, state):
        if state:
            # set the bgs of screens to black
        else:
            # set the bgs of screens to white

class Test(App):
    
    def build(self):
        sm = ScreenManager(transition: FadeTransition())
        sm.add_widget(MainScreen())
        sm.add_widget(SettingsScreen())
        return sm

Test().run()

Kivy:

<MainScreen>:
    id: Main
    name: 'Main'
    BoxLayout:
        orientation: vertical
        Label:
            text: 'Settings below!'
        Button:
            id: 
            text: 'Settings'
            on_release: app.root.current = 'Settings'

<SettingsScreen>:
    id: Settings
    name: 'Settings'
    BoxLayout:
        Label:
            text: 'Dark mode?'
        CheckBox:
            id: darkTheme
            on_active: root.changeTheme(self.state)   

The problem I'm facing with right now is that I can't figure out how to get access to <MainScreen> and <SettingsScreen> classes in order to change the background color. Any help would be appreciated.


Solution

  • If you must access Screens by using id, then you must specify the Screens as children of the ScreenManager in your kv, like this:

    ScreenManager:
        MainScreen:
            id: Main
        SettingsScreen:
            id: Settings
        
    <MainScreen>:
        name: 'Main'
        BoxLayout:
            orientation: 'vertical'
            Label:
                text: 'Settings below!'
            Button:
                id: butt
                text: 'Settings'
                on_release: app.root.current = 'Settings'
    
    <SettingsScreen>:
        name: 'Settings'
        BoxLayout:
            Label:
                text: 'Dark mode?'
            CheckBox:
                id: darkTheme
                on_active: root.changeTheme(self.state)   
    

    If your kv file is named test.kv, then you can eliminate the build() method entirely. Then you can access the Screens using the ids of the root (which is the ScreenManager) of your App.