为什么在外部.kv文件中使用screenmanager的正确.kv代码不工作?

2 投票
2 回答
1306 浏览
提问于 2025-04-18 01:38

这段代码是完全可以正常工作的:

from kivy.app import App
from kivy.lang import Builder

from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition

Builder.load_string("""
#:kivy 1.8

<StartScreen>:
    BoxLayout:
        Label:
            text: "Press Button to"
        Button:
            text: "Start Server"
            on_press:
                root.start_server()
                root.manager.current='stopscreen'

<StopScreen>:
    BoxLayout:
        Label:
            text: "Press Button to"
        Button:
            text: "Stop Server"
            on_press:
                root.stop_server()
                root.manager.current='startscreen'
""")

class StartScreen(Screen): 
    def start_server(self):
        print('Server started.')


class StopScreen(Screen):  
    def stop_server(self):
        print('Server stopped.')


sm = ScreenManager(transition=NoTransition())
sm.add_widget(StartScreen(name='startscreen'))
sm.add_widget(StopScreen(name='stopscreen'))


class MySpecialApp(App):

    def build(self):
        return sm


MySpecialApp().run()

现在,根据Kivy的文档,应该可以把这段代码开头加载的字符串放到一个外部文件里,叫做myspecial.kv。可是,一旦我这么做了,屏幕就变成空白了,什么按钮、文字都没有。为什么会这样呢?我该怎么才能让它正常工作呢?

2 个回答

1

main.py

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


class StartScreen(Screen): 
    def start_server(self):
        print('Server started.')


class StopScreen(Screen):  
    def stop_server(self):
        print('Server stopped.')


class RootScreen(ScreenManager):
    pass


class MySpecialApp(App):
    def build(self):
        return RootScreen()


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

myspecial.kv

<RootScreen>:
    StartScreen:
    StopScreen:


<StartScreen>:
    BoxLayout:
        Label:
            text: "Press Button to"
        Button:
            text: "Start Server"
            on_press:
                root.start_server()
                root.manager.current='stopscreen'


<StopScreen>:
    BoxLayout:
        Label:
            text: "Press Button to"
        Button:
            text: "Stop Server"
            on_press:
                root.stop_server()
                root.manager.current='startscreen'
8

当应用程序启动时,myspecial.kv 文件会被加载,但你在这之前就已经初始化了你的控件。在你运行 sm = ScreenManager(transition=NoTransition()) 的时候,kv 文件还没有加载,所以 ScreenManager 没有你期待的样式。

你应该在 build 方法里面创建你的控件。因为 kv 文件是在这个方法运行之前就加载的,所以一切应该都能正常工作。

撰写回答