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.
Now the two screens will have one manager, which is
ScreenManagement
So in your kv code you call the manager like this:
You can also do like this, if you dont want to make methods:
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.