在 Kivy 中跨屏幕更新标签 (Python) - .kv 和 .py 文件与 ScreenManager 之间(缺乏)交互的问题

Updating Labels across Screens in Kivy (Python) - Problem with (lack of) interactions between .kv and .py files with ScreenManager

我正在尝试构建一个 Kivy 应用程序,它有 2 个屏幕,这些屏幕用不同的文本一遍又一遍地重复使用。

所以我从标签为“First1”的 FirstScreen 转到标签为“Second1”的 SecondScreen,然后回到 FirstScreen,但这次标签为“First2”,然后是 SecondScreen 和“Second2”,依此类推。

此代码非常简单,但在没有指定更新按钮的情况下更新标签文本似乎存在问题。出于某种原因,我的 Python 代码设法更新了文本,但它没有在我的 .kv 文件中更新。因此,例如,我的打印语句会告诉我标签文本是“First2”,但 Kivy 为我显示“First1”。我在下面的屏幕截图中说明了这一点:

通过添加一个在按下时更新文本的按钮,所有内容都会更新、同步并正常工作,但我真的希望它在没有额外用户输入的情况下也能正常工作。有人知道我该怎么做吗?我已经左右搜索了文档和 Whosebug 问题,但似乎找不到我看似简单的问题的答案。

代码如下:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty
from kivy.lang import Builder

S_ID = 1  # global screen ID. I'm using this to detect what text to use.


class FirstScreen(Screen):
    text = StringProperty("")
    lbl = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(FirstScreen, self).__init__(**kwargs)
        global S_ID
        print("\nS_ID is ", S_ID)
        self.update()

    def update(self):
        print("FIRST - UPDATE")
        if S_ID == 1:
            print("FIRST1")
            self.text = "FIRST1"
        elif S_ID == 2:
            print("FIRST2")
            self.text = "FIRST2"
            print("self.lbl.text", self.lbl.text)
        else:
            print("FIRST ELSE")
            self.text = "FIRST ELSE"

    def pressed(self):
        sm.current = "second"


class SecondScreen(Screen):
    text = StringProperty("")

    def __init__(self, **kwargs):
        super(SecondScreen, self).__init__(**kwargs)
        self.update()

    def update(self):
        print("SECOND - UPDATE")
        if S_ID == 1:
            print("SECOND1")
            self.text = "SECOND1"
        elif S_ID == 2:
            print("SECOND2")
            self.text = "SECOND2"
        else:
            print("SECOND ELSE")
            self.text = "SECOND ELSE"

    def pressed(self):
        global S_ID
        S_ID += 1
        FirstScreen.update(FirstScreen())
        sm.current = "first"


sm = ScreenManager()
kv = Builder.load_file("test.kv")
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))

sm.current = "first"


class MyApp(App):

    def build(self):
        return sm


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

这是 .kv 文件:

<FirstScreen>:
    name: "first"
    lbl: lbl:

    GridLayout:
        cols:2
        Label:
            id: lbl
            text: root.text

        Button:
            text: "next"
            on_press: root.pressed()

<SecondScreen>:
    name: "second"

    GridLayout:
        cols:2
        Label:
            text: root.text

        Button:
            text: "next"
            on_press:
                root.pressed()

问题是你的陈述:

FirstScreen.update(FirstScreen())

此语句正在创建 FirstScreen 的新实例并更新该实例。不幸的是,该实例不是您的 GUI 中显示的实例。您可以通过将上述语句替换为:

来更正该错误
    first_screen = self.manager.get_screen('first')
    first_screen.update()

此代码从 ScreenManager 获取 FirstScreen 的实例并在该实例上调用 update()