2016-12-26 10 views
0

Я пытаюсь сделать ScreenManager внутри работы BoxLayout, поэтому я могу установить фиксированную панель инструментов под каждым экраном экрана. Мне удалось показать первый экран (спасибо this question), но, когда я пытаюсь заглянуть на другой экран, приложение вылетает, говоря, что другого экрана нет.switch screenmanager внутри макета

На самом деле, на самом деле нет другого экрана: оба изображения внутри ScreenManagement's 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

Fir вам нужно добавить экраны к экрану.
Для этого вы можете сделать что-то подобное в своем классе 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: No Screen with name» menu »." –

+0

@HenriqueGarcia попробуйте сейчас. Ответ удатет. Забыл установить имена 'self.add_widget (Init (name =" init "))' – EL3PHANTEN

+0

Ошибка не поднимается, но экран не переключается. Self.current изменяется от «init» до «menu», но графический интерфейс остается неизменным. И почему мне нужно передать имя конструктору экрана? Он уже установлен в файле kv .... –

0

С большой помощью @ EL3PHANTEN и this, я установил свой код, и я думаю, я знаю, где была моя ошибка.

Я не могу использовать app.root.sm.current='whateverScreenName' внутри файла kv. Я не могу объяснить, почему, но я предполагаю, что у него есть что-то с момента установки ScreenManagement. Как я думал с самого начала, часть python очень проста.

снова: Спасибо за вашу помощь, @ EL3PHANTEN :)

Вот результат:

ScreenManager inside a BoxLayout to have a Toolbar

Здесь работает фиксированный код питона:

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 

 Смежные вопросы

  • Нет связанных вопросов^_^