switch screenmanager inside layout - python

I'm trying to make a ScreenManager inside a BoxLayout work, so I can have a fixed toolbox below everyScreen the Screen. I managed to show the first screen (thanks to this question), but, when I try to swicth to the other Screen, the app crashes saying that there's no other Screen.
Actually, there really is no other Screen: both prints inside the ScreenManagement's init shows nothing. And I don't know why.
Without the toolbar (only with the ScreeManager(ment) and the necessary tweaks in the code, of course) everything works fine.
I tried to add_widget to the ScreenManagement and the screen_names was populated, but I couldn't switch between the Screens.
What I am missing?
The last part of the error:
screen = self.get_screen(value)
File "C:\Python27\lib\site-packages\kivy\uix\screenmanager.py", line 944, in get_screen
raise ScreenManagerException('No Screen with name "%s".' % name)
ScreenManagerException: No Screen with name "init".
Windows 7, Python 2.7, Kivy 1.9.1
Here is the ClassApp.py:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.clock import Clock
#just solving my weak GPU issue
from kivy import Config
Config.set('graphics', 'multisamples', '0')
kivy.require('1.9.1')
class Init(Screen):
pass
class Menu(Screen):
pass
class ScreenManagement(ScreenManager):
def __init__(self,**kwargs):
print('before super: ', self.screen_names)
super(ScreenManagement,self).__init__(**kwargs)
print('after super: ', self.screen_names)
def switch_to_menu(self):
self.current = 'menu'
print('going to menu')
def switch_to_init(self):
self.current = 'init'
print('going to init')
class ClassAllScreen(BoxLayout):
sm = ScreenManagement()
sm.transition = NoTransition()
pass
class ClassApp(App):
def build(self):
self.root = ClassAllScreen()
return self.root
if __name__ == '__main__':
ClassApp().run()
And here the Class.kv:
<Init>: #first Screen
name: 'init'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
Button:
text:'uppest'
GridLayout:
spacing:10
cols:2
Button:
text:'upper left'
Button:
text:'upper right'
Button:
text:'bottom left'
Button:
text:'bottom right'
Button:
text:'bottomest: go to menu'
on_press:app.root.sm.switch_to_menu()
<Menu>: #second Screen
name: 'menu'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
GridLayout:
spacing:10
cols:2
Button:
text:'upper left'
Button:
text:'upper right'
Button:
text:'bottom left'
Button:
text:'bottom right'
Button:
text:'bottomy'
Button:
text:'bottomest: go to init'
on_press:app.root.sm.switch_to_init()
<ScreenManagement>: #including both the Screens in ScreenManager
Menu:
Init:
<ClassAllScreen>: #all the display with ScreenManager and "Toolbar"
orientation:'vertical'
ScreenManagement:
BoxLayout:
size_hint_y: None
height: 60
spacing: 5
padding: 5,5,0,5
canvas:
Color:
rgba: .1,.1,.1,1
Rectangle:
pos: self.pos
size: self.size
Button:
text:'1'
size_hint_x: None
width: 60
Button:
text:'2'
size_hint_x: None
width: 60
Button:
text:'3'
size_hint_x: None
width: 60

First you need to add the screens to your screenmanager.
To do that, you can do something like this in your ScreenManager class.
def __init__(self,**kwargs):
super(ScreenManagement,self).__init__(**kwargs)
self.add_widget(Init(name="init"))
self.add_widget(Menu(name="menu"))
Now the two screens will have one manager, which is ScreenManagement
So in your kv code you call the manager like this:
Button:
text:'bottomest: go to menu'
on_press:root.manager.switch_to_menu()
You can also do like this, if you dont want to make methods:
Button:
text:'bottomest: go to menu'
on_press:root.manager.current = 'menu'
Also there is a problem with your code, You add the screenmanager to a boxlayout, and try to return the boxlayout. You cannot do that. You can only show one screen at a a time. So I am guessing you want a third screen here. What you should do is retunr the screen manager in your build method, and only add screens to it.
I wrote an example. I dont know if its something like this you want.
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
Builder.load_string("""
<Init>:
name: 'init'
BoxLayout:
orientation:'vertical'
Button:
text:'go to menu'
on_press:root.manager.current = "menu"
<Menu>:
name: 'menu'
BoxLayout:
orientation:'vertical'
Button:
text:'go to init'
on_press:root.manager.current = "init"
<ClassAllScreen>:
BoxLayout:
orientation:'vertical'
Button:
text:'go to init'
on_press:root.manager.current = "init"
Button:
text:'go to menu'
on_press:root.manager.current = "menu"
""")
class Init(Screen):
pass
class Menu(Screen):
pass
class ClassAllScreen(Screen):
pass
class ClassApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(ClassAllScreen(name="main"))
sm.add_widget(Init(name="init"))
sm.add_widget(Menu(name="menu"))
return sm
if __name__ == '__main__':
ClassApp().run()

With the great help of #EL3PHANTEN and this, I fixed my code and I guess I know where was my mistake.
I can't use app.root.sm.current='whateverScreenName' inside kv file. I can't explain why, but I guess it has something with the moment of ScreenManagement's instatiation. As I thought from the begin, the python part is very straightforward.
Again: thanks for your help, #EL3PHANTEN :)
Here is the result:
ScreenManager inside a BoxLayout to have a Toolbar
Here is the working fixed python code:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.clock import Clock
#just solving my weak GPU issue
from kivy import Config
Config.set('graphics', 'multisamples', '0')
kivy.require('1.9.1')
class ScreenManagement(ScreenManager):
pass
class Init(Screen):
pass
class Menu(Screen):
pass
class ClassAllScreen(BoxLayout):
pass
class ClassApp(App):
def build(self):
self.root = ClassAllScreen()
return self.root
if __name__ == '__main__':
ClassApp().run()
And the Class.kv:
#: import NoTransition kivy.uix.screenmanager.NoTransition
<Init>:
name: 'init'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
Button:
text:'uppest'
GridLayout:
spacing:10
cols:2
Button:
text:'upper left'
Button:
text:'upper right'
Button:
text:'bottom left'
Button:
text:'bottom right'
Button:
text:'bottomest: go to menu'
on_press: root.manager.current = 'menu'
<Menu>:
name: 'menu'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
GridLayout:
spacing:10
cols:2
Button:
text:'upper left'
Button:
text:'upper right'
Button:
text:'bottom left'
Button:
text:'bottom right'
Button:
text:'bottomy'
Button:
text:'bottomest: go to init'
on_press: root.manager.current = 'init'
<ScreenManagement>:
transition: NoTransition()
Init:
Menu:
<ClassAllScreen>:
orientation:'vertical'
ScreenManagement:
BoxLayout:
size_hint_y: None
height: 60
spacing: 5
padding: 5,5,0,5
canvas:
Color:
rgba: .1,.1,.1,1
Rectangle:
pos: self.pos
size: self.size
Button:
text:'1'
size_hint_x: None
width: 60
Button:
text:'2'
size_hint_x: None
width: 60
Button:
text:'3'
size_hint_x: None
width: 60

Related

Kivy Nested ScreenManager inside BoxLayout

Something seen with a different flavor each week, Here we go again with more ScreenManager shenanigans!
Screens won't change unless buttons are part of the screen itself, I wanted a universal navbar along the top and then a "display" under it. Both screens work, the buttons to switch between them don't.
(Bonus points if you can tell me how to make each screen its own KV file and still link with the screenmanager)
anyways: CODE
QCManager.py
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
kivy.require('1.9.1')
class MOTD(Screen):
print("MOTD Screen!")
pass
class Search(Screen):
print("Search Screen!")
pass
class ScreenManagement(ScreenManager):
pass
class ClassAllScreen(BoxLayout):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.manager = ScreenManagement()
class ClassApp(App):
def build(self):
self.root = ClassAllScreen()
return self.root
if __name__ == '__main__':
Builder.load_file('./kvfiles/main.kv')
ClassApp().run()
main.kv
#: import NoTransition kivy.uix.screenmanager.NoTransition
<MOTD>:
name: 'motd'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
Label:
text:"The Cake Is a Lie"
<Search>:
name: 'search'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
GridLayout:
spacing:10
cols:2
Button:
text:'Left'
Button:
text:'Right'
Button:
text:'bottom'
<ScreenManagement>:
transition: NoTransition()
MOTD:
Search:
<ClassAllScreen>:
orientation:'vertical'
BoxLayout:
size_hint_y: None
height: 60
spacing: 5
padding: 5
canvas:
Color:
rgba: .1,.1,.1,1
Rectangle:
pos: self.pos
size: self.size
Button:
text:'Menu'
size_hint_x: None
width: 120
on_release: root.manager.current = 'motd'
Button:
text:'Search'
size_hint_x: None
width: 120
on_release: root.manager.current = 'search'
Button:
text:'Add to DB'
size_hint_x: None
width: 120
on_press: print("Button Working")
ScreenManagement:
You __init__() method in the ClassAllScreen class is creating an instance of ScreenManagement. That instance is saved as self.manager, but is not added to your GUI.
In your kv file, the line:
ScreenManagement:
is creating another, different instance of ScreenManagement. This instance of ScreenManagement is the one that is in your GUI.
So anything your do to self.manager in the ClassAllScreen will have no effect on the ScreenManagement that is in your GUI.
The fix is to make sure you are referencing the correct instance of ScreenManagement (and not bother to create any other instances). To do this you can add an ObjectProperty to ClassAllScreen in the kv file, like this:
<ClassAllScreen>:
manager: scr_manager # added ObjectProperty that references the scr_manager id
orientation:'vertical'
BoxLayout:
size_hint_y: None
height: 60
spacing: 5
padding: 5
canvas:
Color:
rgba: .1,.1,.1,1
Rectangle:
pos: self.pos
size: self.size
Button:
text:'Menu'
size_hint_x: None
width: 120
on_release: root.manager.current = 'motd'
Button:
text:'Search'
size_hint_x: None
width: 120
on_release: root.manager.current = 'search'
Button:
text:'Add to DB'
size_hint_x: None
width: 120
on_press: print("Button Working")
ScreenManagement:
id: scr_manager # new id to enable reference to this ScreenManagement instance
And the ClassAllScreen class can then be simplified to:
class ClassAllScreen(BoxLayout):
pass
Just to help out anyone trying to do the same. The fixed code is below
App.py
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
kivy.require('1.9.1')
class MOTD(Screen):
print("MOTD Screen!")
pass
class Search(Screen):
print("Search Screen!")
pass
# class ScreenManagement(ScreenManager):
# pass # Removed, Instanced in kv
class ClassAllScreen(BoxLayout):
pass # Removed code, Done in kv
class ClassApp(App):
def build(self):
self.root = ClassAllScreen()
return self.root
if __name__ == '__main__':
Builder.load_file('./kvfiles/main.kv')
ClassApp().run()
main.kv
#: import NoTransition kivy.uix.screenmanager.NoTransition
<MOTD>:
name: 'motd'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
Label:
text:"The Cake Is a Lie"
<Search>:
name: 'search'
BoxLayout:
orientation:'vertical'
padding:20
spacing:10
GridLayout:
spacing:10
cols:2
Button:
text:'Left'
Button:
text:'Right'
Button:
text:'bottom'
<ClassAllScreen>:
manager:scr_manager
orientation:'vertical'
BoxLayout:
size_hint_y: None
height: 60
spacing: 5
padding: 5
canvas:
Color:
rgba: .1,.1,.1,1
Rectangle:
pos: self.pos
size: self.size
Button:
text:'Menu'
size_hint_x: None
width: 120
on_release: root.manager.current = 'motd'
Button:
text:'Search'
size_hint_x: None
width: 120
on_release: root.manager.current = 'search'
Button:
text:'Add to DB'
size_hint_x: None
width: 120
on_press: print("Button Working")
ScreenManager:
transition: NoTransition()
id: scr_manager
MOTD:
Search:

Kivy Python: buttons and classes for multiple screens

I have a problem with my Kivy Python Code. I have 2 screens: 1st is to navigate to the second screen and on the 2nd screen there is a button to add text to a scrollview...navigating is working but it does not add any text to the scrollview...I think I need some help here! AttributeError: 'super' object has no attribute 'getattr'
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock, mainthread
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
from kivy.effects.scroll import ScrollEffect
from kivy.lang import Builder
Builder.load_string("""
<MenuScreen>:
name: 'mainmenu'
BoxLayout:
spacing: 1
orientation: "vertical"
Label:
text: "MAIN MENU"
Button:
text: 'Go to Screen 2'
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "left"
Button:
text: 'Quit'
on_release: root.manager.current = app.exit_software()
<Screen2>:
name: 'screen2'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "You can add some Text here by pressing the button"
size_hint: None, None
size: self.texture_size
Button:
text: 'Add text!'
size_hint_y: 0.1
on_release: app.add_text()
Button:
text: 'Back to main menu'
size_hint_y: 0.1
on_release:
root.manager.current = 'mainmenu'
root.manager.transition.direction = "right"
""")
# Declare both screens
class MenuScreen(Screen):
pass
class Screen2(Screen):
pass
class AddTextApp(App):
def __init__(self,**kwargs):
super().__init__(**kwargs)
def build(self):
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='mainmenu'))
sm.add_widget(Screen2(name='screen2'))
return sm
def add_text(self):
self.root.ids.label.text += f"Some new Text\n"
self.root.ids.scroll_view.scroll_y = 0
def exit_software(self):
App.get_running_app().stop()
if __name__ == '__main__':
AddTextApp().run()
Thank you very much in advance!
The error occurred because self.root.ids gets access to widgets located in the root widget of the main class. To access the secondary screen elements, you need to add it to the main class (in your case, in ScreenManager) and set its id. Also, you have a lot of imported excess, so that it is clearly visible, I advise you to use Pycharm or something like that.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
kv = """
<MenuScreen>:
name: 'mainmenu'
BoxLayout:
spacing: 1
orientation: "vertical"
Label:
text: "MAIN MENU"
Button:
text: 'Go to Screen 2'
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "left"
Button:
text: 'Quit'
on_release: root.manager.current = app.exit_software()
<Screen2>:
name: 'screen2'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "You can add some Text here by pressing the button"
size_hint: None, None
size: self.texture_size
Button:
text: 'Add text!'
size_hint_y: 0.1
on_release: app.add_text()
Button:
text: 'Back to main menu'
size_hint_y: 0.1
on_release:
root.manager.current = 'mainmenu'
root.manager.transition.direction = "right"
ScreenManager:
MenuScreen:
id: menu_scr
Screen2:
id: scr_2
"""
class MenuScreen(Screen):
pass
class Screen2(Screen):
pass
class AddTextApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
return Builder.load_string(kv)
def add_text(self):
self.root.ids.scr_2.ids.label.text += f"Some new Text\n"
self.root.ids.scr_2.ids.scroll_view.scroll_y = 0
#staticmethod
def exit_software():
App.get_running_app().stop()
if __name__ == '__main__':
AddTextApp().run()

How to switch screens from a dynamically created button in kivy recycleview

Problem
I have a screen (OrderScreen) that populates with buttons if there is data to be processed. I would like the user to click one of the buttons to be brought to another screen (MenuScreen) to process the data. While my intention is to populate the next screen with data from the button, I am currently just trying to get the ScreenManager to change to the next screen after a button press. I added a pass_data() method to the OrderButton and tried to trigger the screen manager there but self.manager.current and root.manager.current were throwing exceptions. Any help would be greatly appreciated.
recycleview_test.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.recycleview import RecycleView
from kivy.uix.screenmanager import ScreenManager, Screen
from random import randint
class MenuScreen(Screen):
def quit(self):
App.get_running_app.stop()
Window.close()
class OrderScreen(Screen):
pass
class OrderButton(Button):
def __init__(self, **kwargs):
super(OrderButton, self).__init__(**kwargs)
def pass_data(self):
print("button pushed")
class OrderScroll(RecycleView):
def __init__(self, **kwargs):
super(OrderScroll, self).__init__(**kwargs)
self.data = [{'text': str(f"Make {randint(10, 25)} items from package #{randint(1,4)}")} for x in range(12)]
class WindowManager(ScreenManager):
pass
class RecycleApp(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
RecycleApp().run()
recycle.kv
#:import Factory kivy.factory.Factory
#: import ScreenManager kivy.uix.screenmanager.ScreenManager
#: import Screen kivy.uix.screenmanager.ScreenManager
#:import App kivy.app.App
<OrderScroll>:
viewclass: 'OrderButton'
manager: None
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
padding: 20
spacing: 10
<OrderButton>:
manager: None
font_size: 32
bold: True
on_release:
root.pass_data()
<WindowManager>:
id: screen_manager
OrderScreen:
id: order_screen
name: "OrderScreen"
manager: screen_manager
MenuScreen:
id: menu_screen
name: 'MenuScreen'
manager: screen_manager
<OrderScreen>:
BoxLayout:
orientation: "vertical"
Label:
text: "Data Buttons"
font_size: 64
size_hint_y: None
# pos_hint: {"x":0, "y":1}
height: 200
OrderScroll:
<MenuScreen>:
BoxLayout:
orientation: "vertical"
Label:
text: "Made it"
font_size: 64
FloatLayout:
Button:
text: 'Keep going'
font_size: 48
size_hint: .8,.5
pos_hint: {"center_x": .5, "center_y": .1}
FloatLayout:
Button:
text: 'Quit'
size_hint: .15,.3
pos_hint: {"center_x": .5, "center_y": .5}
on_release:
root.quit()
Try to create an object of screen manager:
class RecycleApp(App):
def build(self):
self.sm = WindowManager()
return self.sm
And then access it by:
App.get_running_app().sm.current = 'MenuScreen' # in Python
app.sm.current = 'MenuScreen' # in kv

Switching between kivy classes inside one screen

I'm looking for a way to change a part of a screen between 'DownPanel1' and 'DownPanel1' but I would like to avoide creating nex screen class 'ToAvoid'. Is it possible?
from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
kv = '''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
SomeScreen:
ToAvoid:
<Menu#RelativeLayout>
id: main_menu
size_hint_x: None
width: 120
Button:
size_hint_y: None
pos: root.x, root.top - self.height
text: 'SomeScreen'
on_press: app.root.current = "SomeScreen"
<UpScreen>:
BoxLayout:
Button:
text: 'switch'
on_press: app.root.current = "ToAvoid"
<DownPanel1>:
Button:
text: 'DownPanel1'
#on_press:
<DownPanel2>:
Button:
text: 'DownPanel2'
#on_press:
<SomeScreen>:
name: 'SomeScreen'
BoxLayout:
orientation: 'horizontal'
Menu:
BoxLayout:
orientation: 'vertical'
UpScreen:
DownPanel1:
<ToAvoid>:
name: 'ToAvoid'
BoxLayout:
orientation: 'horizontal'
Menu:
BoxLayout:
orientation: 'vertical'
UpScreen:
DownPanel2:
'''
class DownPanel1(BoxLayout):
pass
class DownPanel2(BoxLayout):
pass
class UpScreen(Screen):
pass
class SomeScreen(Screen):
pass
class ToAvoid(Screen):
pass
class ScreenManagement(ScreenManager):
pass
sm = Builder.load_string(kv)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
How about some inception? Just put another ScreenManager inside of the other.
Try this example:
from kivy.app import App
from kivy.lang import Builder
KV = """
ScreenManager:
Screen:
name: "1st"
Button:
text: "next"
on_release:
root.current = "2nd"
Screen:
name: "2nd"
BoxLayout:
Button:
text: "3rd to avoid"
on_release:
root.current = "3rd"
ScreenManager:
id: sm2
Screen:
name: "inner1"
Button:
text: "go to inner 2"
on_release:
sm2.current = "inner2"
Screen:
name: "inner2"
Label:
text: "This is inner 2!"
Screen:
name: "3rd"
Label:
text: "To Avoid!"
"""
class MyApp(App):
def build(self):
return Builder.load_string(KV)
if __name__ == "__main__":
MyApp().run()

.py file interact with .kv file

So i have created some screens and added some properties to them (layouts, buttons, name etc) but everything is on the kivy file. Now, i want to make a function in the python main file which will take me from the starting screen to the next one after a brief time. Though nothing seems to work without me having to move everything from the kivy file to the python file. Any ideas?
.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.behaviors import ButtonBehavior
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class AndAnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class BackgroundLabel(Label):
pass
class CompanyImage(Image):
pass
class LoadingScreen(Screen):
def __init__(self, **kwargs):
super(LoadingScreen, self).__init__(**kwargs)
def ChangeScreen(self):
ScreenManager().current = MainScreen().name
presentation = Builder.load_file("tsalapp.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
.kv
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import Clock kivy.clock.Clock
#: import Color kivy.graphics
#: import Rectangle kivy.graphics
ScreenManagement:
transition: FadeTransition()
LoadingScreen:
MainScreen:
AnotherScreen:
AndAnotherScreen:
<BackgroundLabel>:
background_color: 30,144,255,1
canvas.before:
Color:
rgba: self.background_color
Rectangle:
pos: self.pos
size: self.size
<LoadingScreen>:
name: "main"
id: "yolo"
on_enter: Clock.schedule_once(none, 3)
#app.root.current: "menu"
Image:
source: 'Untitled.png'
height: root.height
width: root.width
allow_stretch: True
keep_ratio: False
AnchorLayout:
Label:
text: "Tsala Inc."
anchor_x: 'center'
anchor_y: 'center'
font_size: root.height/15
<MainScreen>:
name: "menu"
id: "swag"
BoxLayout:
orientation: "vertical"
Button:
text: "Next Page"
background_color: 1,1,4,1
size_hint: (0.5, 0.5)
on_release:
app.root.current= "Another Screen"
Button:
text: "Previous Page"
background_color: 1,4,1,1
size_hint: (0.5, 0.5)
on_release:
app.root.current= "And Another Screen"
<AnotherScreen>:
name: "Another Screen"
GridLayout:
cols: 2
Button:
text: "Previous Page"
background_color: 0,0,1,1
size_hint: (0.25,1)
on_release:
app.root.current = "menu"
Button:
text: "Exit"
background_color: 1,0,0,1
size_hint: (0.25, 1)
on_release:
exit()
<AndAnotherScreen>:
name: "And Another Screen"
BoxLayout:
orientation: "vertical"
Button:
text: "Next Page"
background_color: 1,1,4,1
size_hint: (0.5, 0.5)
on_release:
app.root.current= "menu"
Button:
text: "Nextest Page"
background_color: 1,4,1,1
size_hint: (0.5, 0.5)
on_release:
app.root.current= "Another Screen"
Firstly I recommend create a global variable for screenmanager or place screenmanager in the MainApp as class property and create a list or a dictionary for the screens:
class MyApp(App):
sm = ScreenManager() # screenmanager
screens = {} # dictionary for the screens, I prefer dictionary because string indexes are more convenient
Then in a build method you can create all screens you need and return the screenmanager as root widget:
class MyApp(App):
sm = ScreenManager() # screenmanager
screens = {} # dictionary for the screens, I prefer dictionary because string indexes are more convenient
def build(self):
self.__create_screens()
MyApp.sm.add_widget(MyApp.screens['main_screen'])
return MyApp.sm
def __create_screens(self):
MyApp.screens['main_screen'] = MainScreen(name='mainscreen')
MyApp.screens['another_screen'] = AnotherScreen(name='another_screen')
MyApp.screens['and_another_screen'] = AndAnotherScreen(name='and_another_screen')
So now you can switch your app's screens easily wherever you want using switch_to method:
MyApp.sm.switch_to(MyApp.screens['another_screen'], direction='left', duration=1)

Categories

Resources