Search code examples
pythonpython-3.xkivykivy-language

How to add navigation in kivy using .py file?


I am trying to add navigation in my kivy app using .py file but because the things I tried are not working and I am a complete beginner. I don't know what problem is occurring and I am not able to find any solutions on my own pls help me. I am trying to change the main screen from class Dre to class SecondWindow when the play button is clicked. BTW the things I already tried are tagged now. Pls give the solution in .py file because I am trying to do everything on it. Here is the code. Thanks

import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

class MainWindow(Screen):
    pass



#class ThirdWindow(ScreenManager):
#    def load(self):
#        sm = ScreenManager
#        sm.add_widget(Dre(name='Dre'))
#        sm.add_widget(SecondWindow(name='SecondWindow'))
#        self.sm.current = 'Dre'

class Dre(RelativeLayout):
    def __init__(self, **kwargs):
        super(Dre, self).__init__(**kwargs)
        self.color = [254/255, 102/255, 37/255, 1]
        self.H_color = [254/255, 102/255, 37/255]
        self.sound_theme = None
        self.init_audio()
        # self.kv = Builder.load_file('Levels.py')
        # self.callback()

        if platform in ('linux', 'win', 'macosx'):
            with self.canvas.before:
                self.bg = Rectangle(size=self.size, source='Neo.png')

            self.bind(pos=self.update_bg)
            self.bind(size=self.update_bg)
        else:
            with self.canvas.before:
                self.bg = Rectangle(size=self.size, source='Neon.png')

            self.bind(pos=self.update_bg)
            self.bind(size=self.update_bg)


    def update_bg(self, *args):
        if platform in ('linux', 'win', 'macosx'):
            self.bg.pos = self.pos
            self.bg.size = self.size
            self.add_widget(Label(text='D  R  E  A  M  S',
                          pos_hint={'center_x': .5, 'center_y': .8},
                          font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
            B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
                     pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='')
            # B1.bind(on_press=return self.kv)
            self.add_widget(B1)

        else:
            self.bg.pos = self.pos
            self.bg.size = self.size
            self.add_widget(Label(text='D  R  E  A  M  S',
                                  pos_hint={'center_x': .5, 'center_y': .8},
                                  font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
            B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
                        pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
                        on_press=self.callback)

            self.add_widget(B1)


   # def callback(self, instance):
   #     print('working')
   #     self.manager.current = 'SecondWindow'

    def init_audio(self):

        self.sound_theme = SoundLoader.load('Bg_theme.mp3')
        self.sound_theme.volume = 1
        self.sound_theme.loop = True
        if self.sound_theme:
            self.sound_theme.play()
            print('okay')
        else:
            print('not okay')


class SecondWindow(Screen):
    def __init__(self, **kwargs):
        super(SecondWindow, self).__init__(**kwargs)
        self.color = [254 / 255, 102 / 255, 37 / 255, 1]
        if platform in ('linux', 'win', 'macosx'):
            with self.canvas.before:
                self.bg = Rectangle(size=self.size, color=self.color)





class LabApp(App):
    def build(self):
        return Dre()


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


Solution

  • Here's the correct code for that (at least for me):

    import kivy
    from kivy.app import App
    from kivy.core.audio import SoundLoader
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.textinput import TextInput
    from kivy.uix.button import Button
    from kivy.uix.stacklayout import StackLayout
    from kivy.uix.relativelayout import RelativeLayout
    from kivy.graphics import Rectangle
    from kivy import platform
    from kivy.lang import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen
    
    class SM(ScreenManager):
        pass
        
    
    class MainWindow(Screen, RelativeLayout):
        def __init__(self, **kwargs):
            super(MainWindow, self).__init__(**kwargs)
            self.color = [254/255, 102/255, 37/255, 1]
            self.H_color = [254/255, 102/255, 37/255]
            self.sound_theme = None
            self.init_audio()
            # self.kv = Builder.load_file('Levels.py')
            # self.callback()
    
            if platform in ('linux', 'win', 'macosx'):
                with self.canvas.before:
                    self.bg = Rectangle(size=self.size, source='Neo.png')
    
                self.bind(pos=self.update_bg)
                self.bind(size=self.update_bg)
            else:
                with self.canvas.before:
                    self.bg = Rectangle(size=self.size, source='Neon.png')
    
                self.bind(pos=self.update_bg)
                self.bind(size=self.update_bg)
    
        def bruh(self):
            App.get_running_app().root.current = 'SecondWindow'
    
        def update_bg(self, *args):
            if platform in ('linux', 'win', 'macosx'):
                self.bg.pos = self.pos
                self.bg.size = self.size
                self.add_widget(Label(text='D  R  E  A  M  S',
                              pos_hint={'center_x': .5, 'center_y': .8},
                              font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
                B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
                         pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='', on_press= lambda x: self.bruh())
                # B1.bind(on_press=return self.kv)
                self.add_widget(B1)
    
            else:
                self.bg.pos = self.pos
                self.bg.size = self.size
                self.add_widget(Label(text='D  R  E  A  M  S',
                                      pos_hint={'center_x': .5, 'center_y': .8},
                                      font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
                B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
                            pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
                            on_press=self.callback)
    
                self.add_widget(B1)
    
    
       # def callback(self, instance):
       #     print('working')
       #     self.manager.current = 'SecondWindow'
    
        def init_audio(self):
    
            self.sound_theme = SoundLoader.load('Bg_theme.mp3')
            self.sound_theme.volume = 1
            self.sound_theme.loop = True
            if self.sound_theme:
                self.sound_theme.play()
                print('okay')
            else:
                print('not okay')
    
    
    class SecondWindow(Screen):
        def __init__(self, **kwargs):
            super(SecondWindow, self).__init__(**kwargs)
            self.color = [254 / 255, 102 / 255, 37 / 255, 1]
            if platform in ('linux', 'win', 'macosx'):
                with self.canvas.before:
                    self.bg = Rectangle(size=self.size, color=self.color)
    
    
    class LabApp(App):
        def build(self):
            sm = SM()
            sm.add_widget(MainWindow(name='MainWindow'))
            sm.add_widget(SecondWindow(name='SecondWindow'))
            return sm
        
    
    if __name__ == '__main__':
        LabApp().run()
    

    The main changes here are the fact that the build method for LabApp is required, since the .kv file isn't used; to also inherit the Screen class into the MainWindow class, which is renamed from Dre for less confusing code, since it is essential forScreenManager; and the bruh method in the MainWindow (im not good at naming ok dont roast me) that changes to the SecondWindow screen when the B1 button's on_press event is called. Sorry for the confusing English but at least it's understandable(?) ig