Kivy: ScreenManager - 访问子属性
Kivy: ScreenManager - Accessing child properties
我正在构建一个应用程序,我需要它重复倒计时到零,直到达到时间限制。这一切都很好,但我目前的问题是,当它结束时,我希望其中一个标签显示“已完成”并尝试使用 ids 方法,但我总是收到一条 KeyError: 'count_down1' 消息,因为应用程序崩溃了就在调用 finish_callback() 函数的最后。
我是 kivy 的新手,但我最好的猜测是 self.ids[] 指的是在根小部件(即 WindowManager)中定义的 id,但 id: 'count_down1' 在一个WindowManager 的子窗口部件(即 SecondWindow)。然而,即使这是正确的,我也无法弄清楚如何纠正这个问题,也没有成功地从其他类似问题中提取正确答案。
py文件
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.properties import NumericProperty
from random import randint
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
a = NumericProperty(0)
b = NumericProperty(0)
run_t = 5
min = 3
max = 7
def reset(self):
self.a = 0
self.b = 0
def start(self, *args):
self.a = randint(self.min, self.max)
self.anim = Animation(a = 0, duration = self.a)
if self.run_t - self.b <= self.max:
self.a = self.run_t - self.b
print("a=", self.a, "b=", self.b)
self.anim = Animation(a = 0, duration = self.a)
else:
print(self.run_t - self.b)
self.anim.bind(on_complete = self.start)
self.anim.start(self)
def count_up(self):
self.anim = Animation(b = self.run_t, duration = self.run_t)
self.anim.bind(on_complete = self.finish_callback)
self.anim.start(self)
def finish_callback(self, animation, param):
print('in finish_callback')
end_1 = self.ids['count_down1']
end_1.text = 'Finished'
#^^this is where the error occurs^^
kv = Builder.load_file("updown.kv")
class PageScrollerApp(App):
def build(self):
return kv
if __name__ == "__main__":
PageScrollerApp().run()
kv 文件
WindowManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "home"
FloatLayout:
Button:
pos_hint: {"x":0.4, "y":0.05}
text: "Go!"
on_release:
root.manager.reset()
root.manager.start()
root.manager.count_up()
root.manager.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.manager.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Label:
id: count_up1
text: str(round(root.manager.b, 1))
pos_hint: {"x": 0.4, "y": 0.3}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "medium"
<TextInput>
size_hint: 0.24,0.1
font_size: 35
<Button>
font_size: 20
color:1,0.2,0.5,1
size_hint: 0.2, 0.1
background_color: 0.5,0.8,0.2,1
<Label>
font_size: 20
color:1,0.2,0.5,1
size_hint: 0.2, 0.1
background_color: 0.5,0.2,0.9,1
出于可读性目的,我已尝试删除所有不必要的代码。总之,我认为我的问题是如何访问和更改子窗口小部件的属性?任何帮助将不胜感激!
问题 - KeyError
receive a KeyError: 'count_down1' message as the app crashes right at
the end upon calling the finish_callback() function.
根本原因
id: count_down1
未在 ScreenManager 中定义。它在 SecondWindow()
中定义,但 ScreenManager 无权访问它。
Kv language » Referencing Widgets
id
的范围限于其声明的规则,因此在您的应用中 count_down1
无法在 <SecondWindow>
规则之外访问。
解决方案
- 将
id: second_window
添加到实例化对象,SecondWindow:
以便您可以引用在SecondWindow
中声明的任何id
- 将
self.ids[
count_down1]
替换为self.ids.second_window.ids.count_down1
片段 - kv 文件
WindowManager:
MainWindow:
SecondWindow:
id: second_window
片段 - py 文件
def finish_callback(self, animation, param):
print('in finish_callback')
self.ids.second_window.ids.count_down1.text = 'Finished'
我正在构建一个应用程序,我需要它重复倒计时到零,直到达到时间限制。这一切都很好,但我目前的问题是,当它结束时,我希望其中一个标签显示“已完成”并尝试使用 ids 方法,但我总是收到一条 KeyError: 'count_down1' 消息,因为应用程序崩溃了就在调用 finish_callback() 函数的最后。
我是 kivy 的新手,但我最好的猜测是 self.ids[] 指的是在根小部件(即 WindowManager)中定义的 id,但 id: 'count_down1' 在一个WindowManager 的子窗口部件(即 SecondWindow)。然而,即使这是正确的,我也无法弄清楚如何纠正这个问题,也没有成功地从其他类似问题中提取正确答案。
py文件
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.properties import NumericProperty
from random import randint
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
a = NumericProperty(0)
b = NumericProperty(0)
run_t = 5
min = 3
max = 7
def reset(self):
self.a = 0
self.b = 0
def start(self, *args):
self.a = randint(self.min, self.max)
self.anim = Animation(a = 0, duration = self.a)
if self.run_t - self.b <= self.max:
self.a = self.run_t - self.b
print("a=", self.a, "b=", self.b)
self.anim = Animation(a = 0, duration = self.a)
else:
print(self.run_t - self.b)
self.anim.bind(on_complete = self.start)
self.anim.start(self)
def count_up(self):
self.anim = Animation(b = self.run_t, duration = self.run_t)
self.anim.bind(on_complete = self.finish_callback)
self.anim.start(self)
def finish_callback(self, animation, param):
print('in finish_callback')
end_1 = self.ids['count_down1']
end_1.text = 'Finished'
#^^this is where the error occurs^^
kv = Builder.load_file("updown.kv")
class PageScrollerApp(App):
def build(self):
return kv
if __name__ == "__main__":
PageScrollerApp().run()
kv 文件
WindowManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "home"
FloatLayout:
Button:
pos_hint: {"x":0.4, "y":0.05}
text: "Go!"
on_release:
root.manager.reset()
root.manager.start()
root.manager.count_up()
root.manager.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.manager.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Label:
id: count_up1
text: str(round(root.manager.b, 1))
pos_hint: {"x": 0.4, "y": 0.3}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "medium"
<TextInput>
size_hint: 0.24,0.1
font_size: 35
<Button>
font_size: 20
color:1,0.2,0.5,1
size_hint: 0.2, 0.1
background_color: 0.5,0.8,0.2,1
<Label>
font_size: 20
color:1,0.2,0.5,1
size_hint: 0.2, 0.1
background_color: 0.5,0.2,0.9,1
出于可读性目的,我已尝试删除所有不必要的代码。总之,我认为我的问题是如何访问和更改子窗口小部件的属性?任何帮助将不胜感激!
问题 - KeyError
receive a KeyError: 'count_down1' message as the app crashes right at the end upon calling the finish_callback() function.
根本原因
id: count_down1
未在 ScreenManager 中定义。它在 SecondWindow()
中定义,但 ScreenManager 无权访问它。
Kv language » Referencing Widgets
id
的范围限于其声明的规则,因此在您的应用中 count_down1
无法在 <SecondWindow>
规则之外访问。
解决方案
- 将
id: second_window
添加到实例化对象,SecondWindow:
以便您可以引用在SecondWindow
中声明的任何id
- 将
self.ids[
count_down1]
替换为self.ids.second_window.ids.count_down1
片段 - kv 文件
WindowManager:
MainWindow:
SecondWindow:
id: second_window
片段 - py 文件
def finish_callback(self, animation, param):
print('in finish_callback')
self.ids.second_window.ids.count_down1.text = 'Finished'