Search code examples
classsliderkivybind

Kivy - Slider Class value change on another screen


I have a slider which value changes the label. That was easy to understand. Now the problem is I want to use this value to show on another screen. Eventually I want the slider to show 1-16 images on another screen dependent on what value is selected on the slider. Below is what I have as of now, which works well for that screen, but how do I get this value to show on another screen? I know I have to create a class, which have made multiple attempts and each seems to confuse me more than understand it better.

<NewGameScreen>:
    name: 'newgame'
    BoxLayout:
        orientation: 'vertical'
        height: 100       

        Label:
            text: 'New Game'
            font_size: 70
                Label:
                    text: 'Players'
                    font_size: 30
                    pos: 300, 400

                Slider:
                    id: s1
                    pos: 420, 400
                    width: '250dp'
                    min: 1
                    max: 16
                    step: 1
                    value: 1
                    on_value: s1.value = self.value

                Label:
                    text: '{}'.format(s1.value)
                    font_size: 30
                    pos: 670, 400

Solution

  • You can pass values through underlying ScreenManager. A working example:

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen
    
    kv = '''
    <NewGameScreen>:
        name: 'newgame'
        BoxLayout:
            orientation: 'vertical'
    
            Slider:
                id: s1
                min: 1
                max: 16
                step: 1
                value: 1
                on_value: 
                    root.manager.get_screen('options').label.text = str(self.value)
            Button:
                text: 'Options'
                on_press: 
                    root.manager.transition.direction = 'left'
                    root.manager.current = 'options'
    
    <OptionScreen>:
        label: label
        name: 'options'
        orientation: 'vertical'
        BoxLayout:
            Button:
                text: 'Go back'
                on_press: 
                    root.manager.transition.direction = 'right'
                    root.manager.current = 'newgame'
    
            Label:
                id: label
                text: '1'
    
    '''
    Builder.load_string(kv)
    
    class NewGameScreen(Screen):
        pass
    
    class OptionScreen(Screen):
        pass
    
    class TestApp(App):
        def build(self):
            sm = ScreenManager()
            sm.add_widget(NewGameScreen())
            sm.add_widget(OptionScreen())
            return sm
    
    if __name__ == '__main__':
        TestApp().run()
    

    Update:

    An extended exaple (adding buttons based on slider value):

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.button import Button
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.properties import ObjectProperty
    
    kv = '''
    #:import Label kivy.uix.label.Label
    <NewGameScreen>:
        name: 'newgame'
        slider: slider
        BoxLayout:
            orientation: 'vertical'
    
            Slider:
                id: slider
                min: 1
                max: 16
                step: 1
                value: 1
                on_value: root.update_buttons()
    
            Button:
                text: 'Options'
                on_press: 
                    root.manager.transition.direction = 'left'
                    root.manager.current = 'options'
    
    <OptionScreen>:
        layout: layout
        name: 'options'
        BoxLayout:
            Button:
                text: 'Go back'
                on_press: 
                    root.manager.transition.direction = 'right'
                    root.manager.current = 'newgame'
            BoxLayout:
                orientation: 'vertical'
                id:layout
                Button:
                    text: "1"
    
    '''
    Builder.load_string(kv)
    
    class NewGameScreen(Screen):
        slider = ObjectProperty(None)
        def update_buttons(self, *args):
            layout = self.manager.get_screen('options').layout
            layout.clear_widgets()
            for i in range(int(self.slider.value)):
                layout.add_widget(Button(text=str(i+1))) 
    
    
    class OptionScreen(Screen):
        layout = ObjectProperty(None)
    
    
    class TestApp(App):
        def build(self):
            sm = ScreenManager()
            sm.add_widget(NewGameScreen())
            sm.add_widget(OptionScreen())
            return sm
    
    if __name__ == '__main__':
        TestApp().run()