如何每秒更新数字属性?



我有三个NumericProperteis,我想每秒更新一次。我尝试使用Clock.schedule_interval(),使其类似于我想要的。如何更新数字处理器?我可以使用在Kivy MainLoop中运行的另一个事件吗?或者也许我没有正确更改数字属性?

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock

Builder.load_string("""
<MyLabel>
text: "{}: {}".format(self.title, self.value)
<UpdatingLabels>
GridLayout:
rows: 1
pos: 0, 0
size: root.size
MyLabel:
id: lb0
title: "value 0"
MyLabel:
id: lb1
title: "value 1"
MyLabel:
id: lb2
title: "value 2"
""")

class UpdatingLabels(Widget):
pass

class MyLabel(Label):
value = NumericProperty(0)
title = StringProperty('')
# This not working but the same what i wanna do
# In real case i have values genereted every second
# def clock_def(dt):
#     MyLabel.ids.lb0.value += 1 # or MyLabel.ids.lb0.value = genereted_value_1
#     MyLabel.ids.lb1.value += 2
#     MyLabel.ids.lb2.value += 3
# event = Clock.schedule_interval(clock_def, 1)

class MyApp(App):
def build(self):
return UpdatingLabels()

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

"ids"是实例的属性,而不是类的属性,因此如果要访问它们,请使用类中创建的对象或自身。因此,您无法使用 MyLabel 访问 ID。

解决方案是在 更新标签类中实现逻辑。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock

Builder.load_string(
"""
<MyLabel>
text: "{}: {}".format(self.title, self.value)
<UpdatingLabels>
GridLayout:
rows: 1
pos: 0, 0
size: root.size
MyLabel:
id: lb0
title: "value 0"
MyLabel:
id: lb1
title: "value 1"
MyLabel:
id: lb2
title: "value 2"
"""
)

class UpdatingLabels(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
event = Clock.schedule_interval(self.clock_def, 1)
def clock_def(self, dt):
self.ids.lb0.value += 1
self.ids.lb1.value += 2
self.ids.lb2.value += 3

class MyLabel(Label):
value = NumericProperty(0)
title = StringProperty("")

class MyApp(App):
def build(self):
return UpdatingLabels()

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

Eyllanesc 的解决方案是正确的,但它当然不是唯一的解决方案,如果您想在应用程序上保留逻辑,另一种方法是使用根小部件中的 ID。

由于您的根类是 UpdatingLabels,并且您希望更新其中具有 id 的小部件,因此您可以通过 app.root 访问它们,该小部件始终引用由构建方法返回的小部件。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock

Builder.load_string("""
<MyLabel>
text: "{}: {}".format(self.title, self.value)
<UpdatingLabels>
GridLayout:
rows: 1
pos: 0, 0
size: root.size
MyLabel:
id: lb0
title: "value 0"
MyLabel:
id: lb1
title: "value 1"
MyLabel:
id: lb2
title: "value 2"
""")

class UpdatingLabels(Widget):
pass

class MyLabel(Label):
value = NumericProperty(0)
title = StringProperty('')


class MyApp(App):
def build(self):
Clock.schedule_interval(self.clock_def, 1)
return UpdatingLabels()
def clock_def(self, dt):
self.root.ids.lb0.value += 1
self.root.ids.lb1.value += 2
self.root.ids.lb2.value += 3
if __name__ == '__main__':
MyApp().run()

最新更新