Kivy:将 ScreenManager 添加到 window 不是作为 root?

Kivy: Add ScreenManager to window not as root?

我正在使用 Kivy 并尝试设置一个 ScreenManager,但我不希望该 ScreenManager 成为我 window 中的根小部件。这是一个测试代码片段,演示了我正在尝试做的事情。 (此代码演示了我的问题。)

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget


class MyRootWidget(Widget):

    def __init__(self, **kwargs):
        super(MyRootWidget, self).__init__(**kwargs)

        self.screen_manager = ScreenManager()
        self.add_widget(self.screen_manager)

        # self.add_widget(Label(text='label direct'))


class MyApp(App):

    def build(self):
        root = MyRootWidget()

        new_screen = Screen(name='foo')
        new_screen.add_widget(Label(text='foo screen'))
        root.screen_manager.add_widget(new_screen)
        root.screen_manager.current = 'foo'

        for x in root.walk():
            print x

        return root


if __name__ == '__main__':
    MyApp().run()

当我 运行 这段代码时, window 是空白的,尽管我希望它会显示文本 "foo screen"?

walk() 命令的打印显示根小部件包含屏幕管理器、我的屏幕和标签,如下所示:

<__main__.MyRootWidget object at 0x109d59c80>
<kivy.uix.screenmanager.ScreenManager object at 0x109eb4ae0>
<Screen name='foo'>
<kivy.uix.label.Label object at 0x109ecd390>

这就是我所期望的。

如果我取消注释将标签小部件直接添加到根小部件的行,该标签会按预期显示。

此外,如果我更改 MyApp.build() 方法,使其 returns new_screen 而不是返回 root,它也可以工作,因为我看到了标签 "foo screen" 在显示屏上。

顺便说一句,我不想​​让屏幕管理器成为根小部件的原因是因为我希望能够在任何屏幕处于活动状态(即使屏幕正在过渡的过程中),所以我想我需要屏幕管理器不是 root 才能做到这一点?

此外,我的最终目标是在 window 中有多个 "quadrants",每个都有自己的屏幕管理器,所以我想我需要确保我可以显示屏幕管理器,而不是根小部件才能执行此操作。

因此,如果我有更好的方法来执行此操作,请告诉我。我也不想为此使用 .kv 文件,因为我想根据其他配置选项(我在这个例子中遗漏了)以编程方式设置整个环境。

总的来说,我想知道是否有人知道为什么这段代码不起作用?

谢谢! 布莱恩

问题是您将 ScreenManager 贴在通用 Widget 中。如果你把它放在一个Layout中,它会正常显示,即:

class MyRootWidget(BoxLayout):

有几种可用的布局:http://kivy.org/docs/gettingstarted/layouts.html