Search code examples
pythonkivy

kivy transition between screens


i made a gui with python kivy with a starting screen that has a button in it which generates new screens when pressed, and it also generates new buttons so its easier to pick the screen i need to get in focus but i can't get it working properly cause i can't generate buttons on the newly made screens when they aren't in focus, the script only generates buttons for the screen in focus it seems

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

    
class ScreenManagement(ScreenManager):
    def __init__(self, **kwargs):
        super(ScreenManagement, self).__init__(**kwargs)

sm = ScreenManagement(transition=FadeTransition())        
         
      
class newtab(Screen):
    def __init__(self, **kwargs):
        super(newtab, self).__init__(**kwargs)
        
        self.bt1=(Button(text="New tab", size_hint =(.1, .1)          ,pos_hint ={'center_x':.1, 'center_y':.94}))
        self.add_widget(self.bt1)
        self.bt1.bind(on_release=self.new_tab)
        
        
        self.txt1 = TextInput(text='',size_hint =(.1, .1),        pos_hint ={'center_x':.2, 'center_y':.75}, multiline=True)
        self.add_widget(self.txt1)
        

            
    def transition(self, instance):
        self.manager.current = (instance.text)
        for item in sm.screen_names:
            
            self.bt2=(Button(text=item, size_hint =(.1, .1)          ,pos_hint ={'center_x':(.1*sm.screen_names.index(item)+.1), 'center_y':.84}))
            self.add_widget(self.bt2)
            self.bt2.bind(on_release=self.transition)
        
    def new_tab(self, *args):
                
        n = len(self.manager.screen_names)    ##number of screens+1
        screen = newtab(name="screen {}".format(n))      #make new screen and give it number
        self.manager.add_widget(screen)
        self.manager.current = "screen 0"
               
        for item in sm.screen_names:            
            self.bt2=(Button(text=item, size_hint =(.1, .1)          ,pos_hint ={'center_x':(.1*sm.screen_names.index(item)+.1), 'center_y':.84}))
            self.add_widget(self.bt2)
            self.bt2.bind(on_release=self.transition)

            
sm.add_widget(newtab(name='screen 0'))    
             
class Application(App):
    def build(self):       
        return sm

if __name__ == "__main__":
    Application().run()

Solution

  • I suppose that below is what you expected to get. But I agree with @ApuCoder that you may look for TabbedPanel functionality.

    from kivy.app import App
    from kivy.uix.label import Label
    from kivy.uix.button import Button
    from kivy.uix.textinput import TextInput
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
    
    class ScreenManagement(ScreenManager):
        def __init__(self, **kwargs):
            super(ScreenManagement, self).__init__(**kwargs)
    
    sm = ScreenManagement(transition=FadeTransition())
    
    class newtab(Screen):
        def __init__(self, **kwargs):
            super(newtab, self).__init__(**kwargs)
    
            self.bt1 = (Button(text="New tab", size_hint=(.1, .1), pos_hint={'center_x': .1, 'center_y': .94}))
            self.add_widget(self.bt1)
            self.bt1.bind(on_release=self.new_tab)
    
            self.txt1 = TextInput(text='', size_hint=(.1, .1), pos_hint={'center_x': .2, 'center_y': .75}, multiline=True)
            self.add_widget(self.txt1)
    
            # add all present screen buttons to newly created screen
            for i, screen in enumerate(sm.screens):
                self.bt2 = (Button(text=screen.name, size_hint=(.1, .1), pos_hint={'center_x': (.1 * i + .1), 'center_y': .84}))
                self.add_widget(self.bt2)
                self.bt2.bind(on_release=self.transition)
    
            # add this newly created screen button to all screens
            for screen in sm.screens + [self]:
                screen.bt2 = (Button(text=self.name, size_hint=(.1, .1), pos_hint={'center_x': (.1 * len(sm.screens) + .1), 'center_y': .84}))
                screen.add_widget(screen.bt2)
                screen.bt2.bind(on_release=screen.transition)
    
        def transition(self, instance):
            self.manager.current = instance.text
    
        def new_tab(self, *args):
            n = len(self.manager.screen_names)  ##number of screens+1
            screen = newtab(name="screen {}".format(n))  # make new screen and give it number
            self.manager.add_widget(screen)
            self.manager.current = "screen 0"
    
    sm.add_widget(newtab(name='screen 0'))
    
    class Application(App):
        def build(self):
            return sm
    
    if __name__ == "__main__":
        Application().run()