好的,目前我正在编写程序。它具有通过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__'
否则。
答案 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: