如何每秒更新NumericProperty?

时间:2019-10-22 13:10:35

标签: python python-3.x kivy

我想每秒更新三个NumericProperteis。我尝试使用Clock.schedule_interval(),因为它类似于我想要的。如何更新NumericProperteis?我可以使用在Kivy MainLoop中运行的另一个事件吗?还是我没有正确更改NumericProperty?

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()

2 个答案:

答案 0 :(得分:2)

“ id”是实例的属性,而不是类的属性,因此,如果要访问它们,请在类中使用创建的对象或self。因此,您无法使用MyLabel访问ID。

解决方案是在UpdatingLabels类中实现逻辑。

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()

答案 1 :(得分:1)

Eyllanesc的解决方案是正确的,但当然不是唯一的解决方案,如果您想保持应用程序的逻辑,则可以使用根小部件中的ID。

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

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()