具有预定义布局的Python Kivy Screen管理器不起作用

时间:2018-02-13 10:29:49

标签: python widget kivy screen

My Main类返回ScreenManager的一个实例。这个ScreenManager有一个带有Screen类的小部件,我希望这个Screen类使用一个小部件,它是我之前定义的一个布局。

当我执行代码时,它只显示一个没有更多信息的黑屏。它应该显示一个Button。

这是我的档案minimum.py

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.app import App

class LayoutWithButton(BoxLayout):

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

class MainScreenApp(Screen):

    def __init__(self, **kwargs):
        super(MainScreenApp, self).__init__(**kwargs)
        button_layout = LayoutWithButton()
        self.add_widget(button_layout)

screen_manager = ScreenManager()
screen_manager.add_widget(MainScreenApp(name='main'))

class TestMainApp(App):

    def build(self):
        return screen_manager

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

这是我的档案testmain.kv

<LayoutWithButton>:
    Button:
        text: 'hello'

即便如此,如果我用类self.add_widget(button_layout)替换MainScreenApp类的行self.add_widget(Button()),它也能正常运行。

我做错了什么?

2 个答案:

答案 0 :(得分:3)

问题是在TestMainApp初始化之前不会加载kv文件。当你在此之前实例化MainScreenApp时,kv中定义的规则没有效果。

一个非常简单的解决方案是将MainScreenApp的实例移动到App子类:

class MainApp(App):

    def build(self):
        screen_manager = ScreenManager()
        screen_manager.add_widget(MainScreenApp(name='main'))
        return screen_manager

您还可以在实例化之前强制执行kv加载:

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang.builder import Builder
from kivy.app import App


class LayoutWithButton(BoxLayout):
    pass


class MainScreenApp(Screen):

    def __init__(self, **kwargs):
        super(MainScreenApp, self).__init__(**kwargs)
        button_layout = LayoutWithButton()
        self.add_widget(button_layout)

Builder.load_file("testmain.kv")
screen_manager = ScreenManager()
screen_manager.add_widget(MainScreenApp(name='main'))


class TestApp(App):

    def build(self):
        return screen_manager


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

另一种选择是在你的kv中做所有事情:

from kivy.uix.screenmanager import ScreenManager
from kivy.app import App


class RootWidget(ScreenManager):
    pass


class MainTestApp(App):
    def build(self):
        return MainWindow()


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

<强> maintest.kv:

<LayoutWithButton@BoxLayout>:
    Button:
        text: 'hello'

<MainScreenApp@Screen>:
    LayoutWithButton:

<RootWidget>:
    MainScreenApp:
        name: "main"

答案 1 :(得分:1)

从testmain.kv你应该删除&lt;和&gt;从班级名称。 您只在设计样式时使用它,并且还会多次调用它。

示例代码的外观:

LayoutWithButton:
     Button:
          text: 'hello'

何时使用&lt;和&gt;:

<LayoutWithButton>:
      pos_hint: 0, .5
      Button:
          text: 'hello'

BoxLayout:
    LayoutWithButton:
         pos_hint: 0, .5
祝你好运!