如何在Kivy中为根屏幕调用on_pre_enter函数?

时间:2019-11-14 17:22:21

标签: python kivy

好的,目前我正在编写程序。它具有通过ScreenManager控制的多个屏幕。根屏幕(加载程序时显示的屏幕)上有一个标签,其文本根据外部文件的上下文而有所不同。本来我会用这样的东西:

if __name__ == "__main__":
    with open(*file*) as f:
        data = eval(f.read())
    App.run()

然后,在上述根屏幕中:

def on_pre_enter(self):
    if data == *something*:
        self.ids.*widget_id*.text = *something else*

它可以在除根屏幕以外的任何其他屏幕上使用。我进行了一些研究,发现由于event_dispatch的工作方式,给定的函数(以及on_enter)在根屏幕上不起作用。那么,有没有解决的办法,或者我能做些什么?

编辑:最小的可复制示例。

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.label import Label

class Manager(ScreenManager):
    pass

class WindowOne(Screen):
    def on_pre_enter(self):
        self.ids.label_one.text = data

class WindowTwo(Screen):
    def on_pre_enter(self):
        self.ids.label_two.text = data

class TestApp(App):
    def build(self):
        return design

data = ''
if __name__ == "__main__":
    with open('design.kv') as f:
        design = Builder.load_string(f.read())
    with open('data.txt') as f:
        data = eval(f.read())
    TestApp().run()

design.kv

Manager:
    WindowOne:
    WindowTwo:

<WindowOne>:
    name: "one"
    Label:
        pos_hint: {"x": 0.15, "y": 0.15}
        id: label_one
        font_size: 40
        text: "This Is Window One"
    Button:
        size_hint: (0.2, 0.2)
        on_release:
            app.root.current = 'two'

<WindowTwo>:
    name: "two"
    Label:
        pos_hint: {"x": 0.15, "y": 0.15}
        id: label_two
        font_size: 40
    Button:
        size_hint: (0.2, 0.2)
        on_release:
            app.root.current = 'one'

如果将WindowOne的on_pre_enter更改为on_pre_leave,代码会正常工作,但返回

AttributeError: 'super' object has no attribute '__getattr__'

否则。

1 个答案:

答案 0 :(得分:0)

您的on_pre_enter()方法正在按预期方式被调用。问题是您在该方法中引用了ids字典,并且ids已设置净值(导致您看到错误)。因此,您需要将on_pre_enter调用延迟到定义ids为止。一种方法是创建一个DummyScreen作为初始Screen,然后使用Clock.schedule_once()切换到原始根Screen。为此,请将DummyScreen定义为:

class DummyScreen(Screen):
    def on_enter(self):
        Clock.schedule_once(self.switch_screen)

    def switch_screen(self, dt):
        self.manager.transition = NoTransition()
        self.manager.current = "one"
        self.manager.transition = SlideTransition()

然后在您的kv文件中,添加DummyScreen

Manager:
    DummyScreen:
    WindowOne:
    WindowTwo: