Search code examples
pythonwindowspycharmkivyscreen

How to change screens in Kivy while on FloatLayout()?


This app shows a screen with a video, logo, user input field, and submit button. It uses FloatLayout and GridLayout. How can I use this to switch screens when a valid input is given to the user input? I want to import ScreenManager but it looks like that FloatLayout and ScreenManager are not very compatible.

'''
from kivy.app import App
from kivy.uix.video import Video
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder

class iaScreen(Screen):
    pass

class rtScreen(Screen):
    pass

class MZ_Invest(App):
    def build(self):
        self.root_layout = FloatLayout()
        self.window = GridLayout()
        self.window.cols = 1
        self.window.size_hint = (0.6,0.7)
        self.window.pos_hint = {"center_x":0.5, "center_y":0.5}
        #add widgets

        #Video
        video = Video(source='birds.mp4', state='play', volume = 0)
        video.allow_stretch = False
        video.options = {'eos': 'loop'}
        video.opacity = 0.5


        #Image
        self.window.add_widget(Image(
            source="mzi.png",
            size_hint = (1.5,1.5)
        ))

        #Label
        self.greeting = Label(
            text="How much would you like to invest?",
            font_size = 18,
            color='90EE90'
        )
        self.window.add_widget(self.greeting)

        #User Input
        self.user = TextInput(
            multiline=False,
            padding_y= (20,20),
            size_hint = (1, 0.5)
        )
        self.window.add_widget(self.user)

        #Button
        self.button = Button(
            text="Submit",
            size_hint = (1,0.5),
            bold = True,
            background_color = '90EE90',

        )
        self.button.bind(on_press=self.callback)
        self.window.add_widget(self.button)

        self.root_layout.add_widget(video)
        self.root_layout.add_widget(self.window)

        return self.root_layout

    def callback(self, instance):
        if self.user.text.isnumeric() and int(self.user.text) >= 10000:
            self.greeting.text = "Calculating: $" + self.user.text
            self.greeting.color = '90EE90'
        else:
            self.greeting.text = "Invalid"
            self.greeting.color = "#FF0000"

if __name__ == "__main__":
    MZ_Invest().run()
'''

Solution

  • mz_invest.py:

    from kivy.app import App
    from kivy.uix.video import Video
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.image import Image
    from kivy.uix.button import Button
    from kivy.uix.textinput import TextInput
    from kivy.uix.widget import Widget
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.lang import Builder
    
    class SM(ScreenManager):
    
        def __init__(self, **kwargs):
            super(SM, self).__init__(**kwargs)
    
    class Screen1(Screen):
        
        def __init__(self, **kwargs):
            super(Screen1, self).__init__(**kwargs)
        
        def callback(self, instance):
            
            entry = self.manager.ids['screen1'].ids.my_input.text
            greeting = self.manager.ids['screen1'].ids.my_label
            
            if entry.isnumeric() and int(entry) >= 10000:
                greeting.text = "Calculating: $" + entry
                greeting.color = '90EE90'
                self.manager.current = 'screen2'
                
            else:
                greeting.text = "Invalid"
                greeting.color = "#FF0000"
    
    class Screen2(Screen):
        def __init__(self, **kwargs):
            super(Screen2, self).__init__(**kwargs)
    
    class MZ_Invest(App):
        def build(self):
            sm = SM()
            return sm
    
        
    
    if __name__ == "__main__":
        MZ_Invest().run()
    

    mz_invest.kv:

    <SM>:
    
        Screen1:
            id: screen1
            name: 'screen1'
    
        Screen2
            id: screen2
            name: 'screen2'
            
    <Screen1>:
    
        FloatLayout:
            
            Video:
                source: 'birds.mp4'
                state: 'play'
                volume: 0
                allow_stretch: False
                options: {'eos': 'loop'}
                opacity: 0.5
                
            GridLayout:
                cols: 1
                size_hint: (0.6,0.7)
                pos_hint: {"center_x":0.5, "center_y":0.5}
                
                Image:
                    size_hint: (1.5,1.5)
                
                Label:
                    id: my_label
                    name: 'my_label'
                    text: "How much would you like to invest?"
                    font_size: 18
                    color: '90EE90'
                    
                TextInput:
                    id: my_input
                    name: 'my_input'
                    multiline: False
                    padding_y: (20,20)
                    size_hint: (1, 0.5)
                    
                Button:
                    text:"Submit"
                    size_hint: (1,0.5)
                    bold: True
                    background_color: '90EE90'
                    on_press: root.parent.ids['screen1'].callback(self)
    
    <Screen2>:
        
        Label:
            text:"Welcome to Screen2"