Kivy Screen manager reference in kv language

2020-07-22 06:28发布

问题:

I'm trying to make a main menu that lets me switch Screens when I click a button, but I can't figure out how to reference the manager from the button.

I have a setup for a main menu page (in kv file):

<MainMenu>:  #AnchorLayout
     BoxLayout:
         Button:
             text: "button 1"
         Button:
             text: "change screen"
             on_release: root.manager.current = "OtherPage"

<MainWidget>:
    screen_manger: screen_manager
    ScreenManger:
        id: screen_manger
        Screen:
            name: "MainMenu"
            MainMenu
        Screen:
            name: "OtherPage"
            OtherPage    #this is defined in the kv file, just lazy to type it.

When I click on the Button Change Screen, i get:

AttributeError: 'MainMenu' object has no attribute 'manager'

which, in all honesty doesn't supprise me. I figure I can work around this by writing all the layout in python code and adding a reference to the screen manager in the BoxLayout or MainMenu widgets, but I have no idea how to do this in the kv file.

回答1:

Re-doing the answer after understanding the issue better:

Your MainWidget instance doesn't know about the screen_manager reference, it's not passed to it (and in its rule root refer to the MainWidget instance, not the ScreenManager one.

If you put manager: screen_manager under the declaration of MainWidget instance (line 15), and you add a manager ObjectProperty to the python declaration of MainWidget, then your binding will work.

python:

class MainWidget(Widget):
    manager = ObjectProperty(None)

kv:

<MainWidget>:
    screen_manger: screen_manager
    ScreenManger:
        id: screen_manger
        Screen:
            name: "MainMenu"
            MainMenu:
                manager: screen_manager
        Screen:
            name: "OtherPage"

then it should work as you want it.

edit: also, this wiki entry by qua-non could be helpful https://github.com/kivy/kivy/wiki/Linking-ScreenManager-to-a-different-Widget