2016-12-26 97 views
0

我想在一個BoxLayout工作內做一個ScreenManager,所以我可以有一個固定的工具箱在屏幕下方的每屏幕下。我設法顯示第一個屏幕(感謝this question),但是,當我嘗試切換到另一個屏幕時,該應用程序崩潰,說沒有其他屏幕。開關screenmanager裏面佈局

實際上,其實並沒有其他的屏幕: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". 

Windows 7中,Python 2.7版,Kivy 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() 

這裏的類.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 

回答

0

冷杉你需要將屏幕添加到你的屏幕管理器。
爲此,您可以在ScreenManager類中執行類似操作。

def __init__(self,**kwargs): 
    super(ScreenManagement,self).__init__(**kwargs) 
    self.add_widget(Init(name="init")) 
    self.add_widget(Menu(name="menu")) 

現在兩個屏幕將有一個經理,這是ScreenManagement
因此,在你千伏代碼調用這樣的管理者:

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,然後嘗試返回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() 
+0

感謝您的回答。但雖然打印表明我有一個名爲「菜單」的屏幕,但仍會出現此錯誤: 「ScreenManagerException:無名稱的屏幕」菜單「。」 –

+0

@HenriqueGarcia立即嘗試。回答udatet。忘了設置名稱'self.add_widget(Init(name =「init」))' – EL3PHANTEN

+0

沒有錯誤發生,但屏幕沒有切換。 self.current從'init'更改爲'menu',但GUI保持不變。 爲什麼我需要將名稱傳遞給Screen構造函數?它已經在kv文件中設置.... –

0

在@ EL3PHANTEN和this的幫助下,我修復了我的代碼,我想我知道我的錯誤在哪裏。

我不能在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() 

而類.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