2016-12-26 5 views
0

Ich versuche, einen ScreenManager in einem BoxLayout arbeiten zu lassen, damit ich unter jedem Bildschirm eine feste Toolbox haben kann. Ich habe es geschafft, den ersten Bildschirm zu zeigen (danke an this question), aber wenn ich versuche, auf den anderen Bildschirm zu switchen, stürzt die App ab und sagt, dass es keinen anderen Bildschirm gibt.Switch Screenmanager im Layout

Eigentlich gibt es wirklich keinen anderen Bildschirm: beide Drucke innerhalb des ScreenManagements init zeigt nichts. Und ich weiß nicht warum.

Ohne die Toolbar (nur mit dem ScreeManager (ment) und den notwendigen Verbesserungen im Code, natürlich) funktioniert alles gut.

Ich habe versucht, add_widget zum ScreenManagement und die Screen-Namen wurde ausgefüllt, aber ich konnte nicht zwischen den Bildschirmen wechseln.

Was ich vermisse?

Der letzte Teil des Fehlers:

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". 

7 Windows Python 2.7, Kivy 1.9.1

Hier ist der 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() 

Und hier die Klasse .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 

Antwort

0

Tanne st müssen Sie die Bildschirme zu Ihrem Screenmanager hinzufügen.
Um dies zu tun, können Sie so etwas in Ihrer ScreenManager-Klasse tun.

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

Nun werden die beiden Bildschirme einen Manager haben, die ScreenManagement
Also in Ihrem kv-Code ist, dass Sie den Manager wie folgt aufrufen:

Button: 
    text:'bottomest: go to menu' 
    on_press:root.manager.switch_to_menu() 

Sie können auch wie dies tun, wenn Sie nicht wollen Methoden machen:

Button: 
    text:'bottomest: go to menu' 
    on_press:root.manager.current = 'menu' 

auch ein Problem mit dem Code vorhanden ist, fügen Sie den Screenmanager zu einem BoxLayout, und versuchen zurückzukehren das Boxlayout. Das kannst du nicht tun. Sie können jeweils nur einen Bildschirm anzeigen. Ich nehme an, Sie wollen hier einen dritten Bildschirm. Was Sie tun sollten, ist, den Screen-Manager in Ihrer Erstellungsmethode erneut aufzurufen und nur Bildschirme hinzuzufügen.
Ich schrieb ein Beispiel. Ich weiß nicht, ob es so etwas ist, das du willst.

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

Danke für die Antwort. Aber obwohl der Ausdruck sagt, dass ich einen Bildschirm namens "Menü" habe, tritt der Fehler immer noch auf: "ScreenManagerException: Kein Bildschirm mit Namen" -Menü "." –

+0

@HenriqueGarcia versuchen Sie es jetzt. Beantworten Sie die Antwort. Habe vergessen die Namen 'self.add_widget (Init (name = "init")) '' – EL3PHANTEN

+0

einzustellen Es wird kein Fehler angezeigt, aber der Bildschirm schaltet nicht um. Der self.current wechselt von 'init' zu 'menu', aber die GUI bleibt gleich. Und warum muss ich den Namen an den Screen-Konstruktor übergeben? Es ist bereits in der kv-Datei eingestellt .... –

0

Mit der großen Hilfe von @ EL3PHANTEN und this, fest ich meinen Code, und ich glaube, ich weiß, wo mein Fehler war.

Ich kann app.root.sm.current='whateverScreenName' in kv-Datei nicht verwenden. Ich kann nicht erklären, warum, aber ich denke, es hat etwas mit dem Moment der Installation von ScreenManagement. Wie ich von Anfang an dachte, ist der Python-Teil sehr einfach.

Nochmals: Danke für Ihre Hilfe, @ EL3PHANTEN :)

Hier ist das Ergebnis:

ScreenManager inside a BoxLayout to have a Toolbar

Hier ist die Arbeits festen 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() 

Und die 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