在布局中切换屏幕管理器
switch screenmanager inside layout
我正在尝试在 BoxLayout 中创建一个 ScreenManager,这样我就可以在 Screen 的 everyScreen 下面有一个固定的工具箱。我设法显示了第一个屏幕(感谢 this question),但是,当我尝试切换到另一个屏幕时,应用程序崩溃并提示没有其他屏幕。
实际上,确实没有其他屏幕:ScreenManagement 的 init 中的两个打印都没有显示任何内容。我也不知道为什么。
没有工具栏(当然只有 ScreeManager(ment) 和代码中的必要调整)一切正常。
我尝试 add_widget 到 ScreenManagement 并且 screen_names 已填充,但我无法在屏幕之间切换。
我错过了什么?
最后一部分错误:
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".
Windows7,Python2.7,基维 1.9.1
这里是 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()
这里是 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
首先您需要将屏幕添加到您的屏幕管理器。
为此,您可以在 ScreenManager class 中执行类似的操作。
def __init__(self,**kwargs):
super(ScreenManagement,self).__init__(**kwargs)
self.add_widget(Init(name="init"))
self.add_widget(Menu(name="menu"))
现在两个屏幕将有一个管理器,即ScreenManagement
因此,在您的 kv 代码中,您可以这样调用管理器:
Button:
text:'bottomest: go to menu'
on_press:root.manager.switch_to_menu()
你也可以这样做,如果你不想制作方法:
Button:
text:'bottomest: go to menu'
on_press:root.manager.current = 'menu'
你的代码也有问题,你将screenmanager添加到boxlayout,然后尝试return boxlayout。你不能这样做。您一次只能显示一个屏幕。所以我猜你想要第三个屏幕。你应该做的是在你的构建方法中重新启动屏幕管理器,并且只向它添加屏幕。
我写了一个例子。不知道这样的是不是你想要的
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()
在@EL3PHANTEN 和 的大力帮助下,我修复了我的代码,我想我知道我的错误在哪里了。
我无法在 kv 文件中使用 app.root.sm.current='whateverScreenName'
。我无法解释原因,但我猜它与 ScreenManagement 的启动时刻有关。正如我从一开始就认为的那样,python 部分非常简单。
再次感谢您的帮助,@EL3PHANTEN :)
结果如下:
ScreenManager inside a BoxLayout to have a Toolbar
这是固定的 python 代码:
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()
和 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
我正在尝试在 BoxLayout 中创建一个 ScreenManager,这样我就可以在 Screen 的 everyScreen 下面有一个固定的工具箱。我设法显示了第一个屏幕(感谢 this question),但是,当我尝试切换到另一个屏幕时,应用程序崩溃并提示没有其他屏幕。
实际上,确实没有其他屏幕:ScreenManagement 的 init 中的两个打印都没有显示任何内容。我也不知道为什么。
没有工具栏(当然只有 ScreeManager(ment) 和代码中的必要调整)一切正常。
我尝试 add_widget 到 ScreenManagement 并且 screen_names 已填充,但我无法在屏幕之间切换。
我错过了什么?
最后一部分错误:
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".
Windows7,Python2.7,基维 1.9.1
这里是 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()
这里是 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
首先您需要将屏幕添加到您的屏幕管理器。
为此,您可以在 ScreenManager class 中执行类似的操作。
def __init__(self,**kwargs):
super(ScreenManagement,self).__init__(**kwargs)
self.add_widget(Init(name="init"))
self.add_widget(Menu(name="menu"))
现在两个屏幕将有一个管理器,即ScreenManagement
因此,在您的 kv 代码中,您可以这样调用管理器:
Button:
text:'bottomest: go to menu'
on_press:root.manager.switch_to_menu()
你也可以这样做,如果你不想制作方法:
Button:
text:'bottomest: go to menu'
on_press:root.manager.current = 'menu'
你的代码也有问题,你将screenmanager添加到boxlayout,然后尝试return boxlayout。你不能这样做。您一次只能显示一个屏幕。所以我猜你想要第三个屏幕。你应该做的是在你的构建方法中重新启动屏幕管理器,并且只向它添加屏幕。
我写了一个例子。不知道这样的是不是你想要的
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()
在@EL3PHANTEN 和
我无法在 kv 文件中使用 app.root.sm.current='whateverScreenName'
。我无法解释原因,但我猜它与 ScreenManagement 的启动时刻有关。正如我从一开始就认为的那样,python 部分非常简单。
再次感谢您的帮助,@EL3PHANTEN :)
结果如下:
ScreenManager inside a BoxLayout to have a Toolbar
这是固定的 python 代码:
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()
和 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