具有预定义布局的Python Kivy屏幕管理器不';行不通

具有预定义布局的Python Kivy屏幕管理器不';行不通,python,widget,kivy,screen,Python,Widget,Kivy,Screen,我的主类返回ScreenManager的一个实例。这个ScreenManager有一个带有Screen类的小部件,我希望这个Screen类使用一个我前面定义的布局小部件 当我执行代码时,它只显示一个黑屏,没有更多信息。它应该显示一个按钮 这是我的文件minimum.py: from kivy.uix.boxlayout import BoxLayout from kivy.uix.screenmanager import ScreenManager, Screen from kivy.app i

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

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

这是我的文件
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\u widget(button())
替换MainScreenApp类的行
self.add\u widget(button())
,它仍然可以正常工作


我做错了什么?

从testmain.kv中,您应该从类名中删除该。 您仅在设计样式时使用它,并且还会多次调用它

示例代码的外观:

何时使用<和>:

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

BoxLayout:
    LayoutWithButton:
         pos_hint: 0, .5
:
位置提示:0,5
按钮:
短信:“你好”
盒子布局:
LayoutWith按钮:
位置提示:0,5

祝你好运

从testmain.kv中,您应该从类名中删除。 您仅在设计样式时使用它,并且还会多次调用它

示例代码的外观:

何时使用<和>:

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

BoxLayout:
    LayoutWithButton:
         pos_hint: 0, .5
:
位置提示:0,5
按钮:
短信:“你好”
盒子布局:
LayoutWith按钮:
位置提示:0,5

祝你好运

问题是在初始化
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"
:
按钮:
短信:“你好”
:
LayoutWith按钮:
:
MainScreenApp:
名称:“主要”

问题是在初始化
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"
:
按钮:
短信:“你好”
:
LayoutWith按钮:
:
MainScreenApp:
名称:“主要”

谢谢你的建议!谢谢你的建议!谢谢它适用于该解决方案。我还发现,我可以使用时钟将小部件添加到下一个周期中:``类MainScreenApp(屏幕):def uu init uu(self,**kwargs):super(MainScreenApp,self)。u init uu(**kwargs)时钟。计划一次(self._finish init)def u init(self,dt):self.add小部件(LayoutWithButton())``谢谢!它与该解决方案配合使用。我还发现我可以使用时钟将小部件添加到下一个周期:```类MainScreenApp(屏幕):def uu init u u(self,**kwargs):super(MainScreenApp,self)。u init(**kwargs)时钟。计划一次(self.u finish_init)def_finish_init(self,dt):self.add_小部件(LayoutWithButton())```