首页 > 解决方案 > 使用 Clock.Interval 更新 Kivy 中的可重用标签小部件

问题描述

我正在开发一个多页 Kivy 应用程序,我想在多个页面中有一个时钟小部件。我能够在每个页面上将它作为一个单独的实例来实现,但我想将它更改为可重用的小部件,但它不会在间隔期间更新

这是 .kv 文件的实现

ScreenManager:
id: screen_manager
HomeScreen:
    id: home_screen
    name: 'home_screen'
    manager: 'screen_manager'

<ClockWidget>:
    Label:
        text_size: self.size
        halign: 'left'
        valign: 'middle'
        id: clocktime
        text: root.ClockTimeDisplay

<HomeScreen>:
    orientation: 'vertical'
    ScrollView:
        do_scroll_x: True
        scroll_distance: 20
        BoxLayout:
            orientation: 'vertical'
            ClockWidget:

这是 .py 文件。在 update_clock 函数中,我曾一次或多次尝试过所有 3 种实现。它正确打印时间但不更新标签,一直说“虚拟文本”。

class ClockWidget(Label):
    ClockTimeDisplay = StringProperty()
    ClockTimeDisplay = "dummy text"
    text = ClockTimeDisplay

    def __init__(self, **kwargs):
        super(ClockWidget, self).__init__(**kwargs)

    def update_clock(self, *args):
        print(self.text)
        #I've tried all 3 of these implimentations at one time or another.
        self.ClockTimeDisplay = str(datetime.now().strftime('%H:%M:%S'))
        self.text = str(datetime.now().strftime('%H:%M:%S'))
        self.ids.clocktime.text = str(datetime.now().strftime('%H:%M:%S'))

        return ClockTimeDisplay


class HomeScreen(Screen):
    pass


class regatta_racer(App):
    def build(self):
        clock_widget = ClockWidget()
        Clock.schedule_interval(clock_widget.update_clock, .1)
        return Builder.load_file('regatta_racer.kv')


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

我也尝试在 ClockWidget 内的 on_load 函数中触发间隔,但这也不起作用。

任何帮助将不胜感激。

标签: python-3.xkivykivy-language

解决方案


问题是在 build 方法中创建的 ClockWidget 与在 .kv 中作为 BoxLayout 的子项创建的 ClockWidget 不同,在您的情况下,只有 Clock 只调用第一个的 update_clock 方法。

另一方面,我认为没有必要在 ClockWidget 中创建一个新的 StringProperty,因为它是一个标签并且具有属性“文本”,另一个奇怪的事情是一个标签有另一个标签作为孩子。

考虑到上述情况,解决方案是:

from datetime import datetime

from kivy.app import App

from kivy.clock import Clock
from kivy.lang import Builder

from kivy.uix.screenmanager import Screen
from kivy.uix.label import Label


class ClockWidget(Label):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_interval(self.update_clock, 0.1)

    def update_clock(self, *args):
        self.text = datetime.now().strftime("%H:%M:%S")


class HomeScreen(Screen):
    pass


class regatta_racer(App):
    def build(self):
        return Builder.load_file("regatta_racer.kv")


if __name__ == "__main__":
    regatta_racer().run()
ScreenManager:
    id: screen_manager
    HomeScreen:
        id: home_screen
        name: 'home_screen'
        manager: 'screen_manager'

<ClockWidget>:
    text_size: self.size
    halign: 'left'
    valign: 'middle'

<HomeScreen>:
    orientation: 'vertical'
    ScrollView:
        do_scroll_x: True
        scroll_distance: 20
        BoxLayout:
            orientation: 'vertical'
            ClockWidget:

推荐阅读