切换屏幕管理器内部布局 [英] switch screenmanager inside layout
问题描述
我正在尝试使BoxLayout内的ScreenManager正常工作,因此我可以在屏幕的EveryScreen下面拥有一个固定的工具箱.我设法显示了第一个屏幕(由于这个问题 ),但是,当我尝试切换到另一个屏幕时,该应用程序崩溃,提示没有其他屏幕.
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.
实际上,确实没有其他屏幕:ScreenManagement的 init 中的两个打印均不显示任何内容.而且我不知道为什么.
Actually, there really is no other Screen: both prints inside the ScreenManagement's init shows nothing. And I don't know why.
没有工具栏(当然只有ScreeManager(ment)和代码中的必要调整),一切正常.
Without the toolbar (only with the ScreeManager(ment) and the necessary tweaks in the code, of course) everything works fine.
我试图将add_widget添加到ScreenManagement中,并且填充了screen_names,但是我无法在各个Screen之间切换.
I tried to add_widget to the ScreenManagement and the screen_names was populated, but I couldn't switch between the Screens.
我想念什么?
错误的最后一部分:
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
Windows 7, Python 2.7, Kivy 1.9.1
这是ClassApp.py:
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()
这里是Class.kv:
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
推荐答案
首先,您需要将屏幕添加到屏幕管理器中.
为此,您可以在ScreenManager类中执行类似的操作.
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"))
现在两个屏幕将有一个管理员,即ScreenManagement
因此,在您的kv代码中,您可以像这样致电经理:
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'
您的代码也有问题,您将screenmanager添加到boxlayout,然后尝试返回boxlayout.你不能这样做.您一次只能显示一个屏幕.所以我猜您想在这里显示第三个屏幕.您应该做的是在构建方法中重新调整屏幕管理器,并仅向其中添加屏幕.
我写了一个例子.我不知道您是否想要这样的东西.
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()
这篇关于切换屏幕管理器内部布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!