更改屏幕时保持工具栏kivy

时间:2018-06-04 04:33:37

标签: python kivy toolbar

所以我有一个工具栏,我想用它在屏幕之间切换,但我希望它能在我自由更换屏幕的同时留在那里。
如果我尝试将一个GridLayout放在一个ScreenManager类中,它会给我一个错误,所以我正在创建一个GridLayout并将一个Screen Manager嵌入其中。但它似乎不像我想要的那样工作。

storeapp.py

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout

class ScreenSwitcher(ScreenManager):
    def __init__(self, **kwargs):
        super(ScreenSwitcher, self).__init__(**kwargs)
        self.add_widget(ScreenOne(name='sone'))
        self.add_widget(ScreenTwo(name='stwo'))

class ScreenOne(Screen):
    pass

class ScreenTwo(Screen):
    pass

class MainScreen(GridLayout):
    manager = ScreenSwitcher()

class StoreApp(App):
    def build(self):
        return MainScreen()

if __name__ == "__main__":

    StoreApp().run()

store.kv

#:kivy 1.10.1

<ToolBar@BoxLayout>:
    size_hint_y: None
    height: 35
    pos_hint: {'top': 1, 'y': 0}
    padding: 5,2,5,2
    spacing: 5

    canvas:
        Color:
            rgba: .7, 1, .7, 1
        Rectangle:
            pos: self.pos
            size: self.size

<ToolButton@Button>:
    color: 0,0,0,1
    align: 'center'

<ScreenOne>:
    Label:
        text: 'SCREEN ONE'
        font_size:50

<ScreenTwo>:
    Label:
        text: 'SCREEN TWO'
        font_size:50

<MainScreen>:
    rows: 2
    size_hint: 1, 1

    ToolBar:
        ToolButton:
            text: 'Screen one'
            on_press:
                root.manager.current = 'sone'

        ToolButton:
            text: 'Screen two'
            on_press:
                root.manager.current = 'stwo'

    ScreenSwitcher:

问题:两个屏幕重叠,按下按钮不会改变任何内容。

2 个答案:

答案 0 :(得分:0)

这里有一个解决方案:Python Kivy screen manager wiget scope

但我发现,对于初学者来说,如何做到这一点并不容易理解解释,所以这就是我的:

python文件:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout

class ScreenSwitcher(ScreenManager):
     #The screens can be added on the __init__ method like this or on the .kv file
    def __init__(self, **kwargs):
        super(ScreenSwitcher, self).__init__(**kwargs)
        self.add_widget(ScreenOne(name='sone'))
        self.add_widget(ScreenTwo(name='stwo'))

#Can be moved to another file, but needs to be imported
class ScreenOne(Screen):
    pass

#Can be moved to another file, but needs to be imported
class ScreenTwo(Screen):
    pass

class MainScreen(GridLayout):
    pass

class StoreApp(App):
    def build(self):
        return MainScreen()

if __name__ == "__main__":

    StoreApp().run()

kivy文件:

#:kivy 1.10.1

<ToolBar@BoxLayout>:
    size_hint_y: None
    height: 35
    pos_hint: {'top': 1, 'y': 0}
    padding: 5,2,5,2
    spacing: 5

    canvas:
        Color:
            rgba: .7, 1, .7, 1
        Rectangle:
            pos: self.pos
            size: self.size

<ToolButton@Button>:
    color: 0,0,0,1
    align: 'center'

#Can be moved to another file if included with #:include filename.kv
<ScreenOne>:
    Label:
        text: 'SCREEN ONE'
        font_size:50

#Can be moved to another file if included with #:include filename.kv
<ScreenTwo>:
    Label:
        text: 'SCREEN TWO'
        font_size:50

#GridLayout used to separate the toolbar from the App's screens
<MainScreen>:
    rows: 2
    size_hint: 1, 1

    ToolBar:
        ToolButton:
            text: 'Screen one'
            on_press:
                root.ids.SS.current = 'sone'
                #Use root.ids to find the ID of your ScreenManager class and 
                #use it to call what you want from there

        ToolButton:
            text: 'Screen two'
            on_press:
                root.ids.SS.current = 'stwo'
                #Use root.ids to find the ID of your ScreenManager class and
                #use it to call what you want from there

    ScreenSwitcher:
        id: SS #Put an ID to your ScreenManager class
        #instead of adding the screens on the __init__method you can also do
        #ScreenOne:
        #ScreenTwo:

答案 1 :(得分:0)

问题

Kivy App没有切换屏幕,因为有两个 ScreenSwitcher 实例。一个实例由ScreenSwitcher:在kv文件中实例化。第二个实例由manager = ScreenSwitcher()在Python脚本中实例化。

按钮的 on_press 事件正在引用 ScreenSwitcher 的第二个实例。

解决方案

store.py

  1. 添加from kivy.properties import ObjectProperty
  2. manager = ScreenSwitcher()替换为manager = ObjectProperty(None)
  3. class MainScreen(GridLayout):
        manager = ObjectProperty(None)
    

    store.kv

    1. manager: manager之后添加<MainScreen>:。这是为了将 ObjectProperty 连接到 ScreenSwitcher 的id。
    2. id: manager
    3. 之后添加ScreenSwitcher:

      <MainScreen>:
          manager: manager
          rows: 2
          size_hint: 1, 1
      
          ...
      
          ScreenSwitcher:
              id: manager
      

      有关详细信息,请参阅示例和输出。

      实施例

      store.py

      from kivy.app import App
      from kivy.uix.screenmanager import Screen
      from kivy.uix.gridlayout import GridLayout
      from kivy.properties import ObjectProperty
      
      
      class ScreenOne(Screen):
          pass
      
      
      class ScreenTwo(Screen):
          pass
      
      
      class MainScreen(GridLayout):
          manager = ObjectProperty(None)
      
      
      class StoreApp(App):
          def build(self):
              return MainScreen()
      
      
      if __name__ == "__main__":
          StoreApp().run()
      

      store.kv

      #:kivy 1.10.1
      
      <ToolBar@BoxLayout>:
          size_hint_y: None
          height: 35
          pos_hint: {'top': 1, 'y': 0}
          padding: 5,2,5,2
          spacing: 5
      
          canvas:
              Color:
                  rgba: .7, 1, .7, 1
              Rectangle:
                  pos: self.pos
                  size: self.size
      
      <ToolButton@Button>:
          color: 0,0,0,1
          align: 'center'
      
      <ScreenOne>:
          Label:
              text: 'SCREEN ONE'
              font_size:50
      
      <ScreenTwo>:
          Label:
              text: 'SCREEN TWO'
              font_size:50
      
      <MainScreen>:
          manager: manager
          rows: 2
          size_hint: 1, 1
      
          ToolBar:
              ToolButton:
                  text: 'Screen one'
                  on_press:
                      root.manager.current = 'sone'
      
              ToolButton:
                  text: 'Screen two'
                  on_press:
                      root.manager.current = 'stwo'
      
          ScreenSwitcher:
              id: manager
      

      输出

      Img01 - App Startup Img02 - ScreenTwo