按下按钮后如何在ModalView中创建倒数计时器?

时间:2020-03-17 18:59:45

标签: kivy

我正在尝试创建一个带有计时器的modalview。按下“开始”按钮后,将出现一个模式视图,并且应该开始倒计时。但是,我收到一条valueerror消息。 ValueError:TimerView.timer格式无效(在0x0000017AD40D6180 >>>处获得main.TimerView对象)。我可以知道代码的哪一部分是错误的吗?预先感谢。

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, WipeTransition, NoTransition, SlideTransition
from kivymd.theming import ThemeManager
from kivy.properties import StringProperty, NumericProperty
from kivy.uix.modalview import ModalView
from kivymd.uix.label import MDLabel
from kivy.clock import Clock

class TimerView(ModalView):
    number = NumericProperty(15)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.background = "transparent_image.png"
        self.background_color = [1/3,1/3,1/3,0.8]
        self.auto_dismiss = False
        self.size_hint = (None,None)
        self.size = (150,50)
        timer_countdown = MDLabel(font_style = 'H1', theme_text_color = 'Primary',
                                  text = str(self.number), halign = 'center',
                                  text_color = (1,1,1,1), size_hint_y = None)
        self.add_widget(timer_countdown)

    def decrement_time(self, dt):
        self.number -= 1

    def start(self,*args):
        self.timer = Clock.schedule_interval(self.decrement_time, 1)

    def stop(self):
        Clock.unschedule(self.timer)

class MainScreen(Screen):
    pass

class BeginScreen(Screen):
    pass

class MyScreenManager(ScreenManager):

    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.view = TimerView()

    def open_view(self):
        self.view.bind(on_open=self.view.start)
        self.view.open()

main_widget_kv = ('''
#: import ScrollEffect kivy.effects.scroll.ScrollEffect

MyScreenManager:
    BeginScreen:

<BeginScreen>:
    begin_button:begin_button
    name: "begin"
    canvas.before:
        Color: 
            rgb: .1, .1, .1
    FloatLayout:
        id: begin_layout
        Button:
            id: begin_button
            text: 'Begin'
            font_size: 24
            on_press: app.root.open_view()
            size_hint: (.4,.25)
            pos_hint: {"center_x":.5, "center_y":.2}
            color: [0,0,0,1]


''')

class TestApp(MDApp):

    def __init__(self,**kwargs):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Red"
        super().__init__(**kwargs)

    def build(self):
        main_widget = Builder.load_string(main_widget_kv)
        return main_widget


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

1 个答案:

答案 0 :(得分:1)

在python代码中设置text的{​​{1}}时,它将使用当时的值,并且不会自动更改。如果您在Label中执行相同的操作,它将自动更新(前提是kv引用了text)。因此,仅更改Property对您的self.number timer_countdown无效。

因此,您需要显式更新Label。这是执行此操作的代码的修改版本:

text

class TimerView(ModalView): number = NumericProperty(15) def __init__(self, **kwargs): super().__init__(**kwargs) self.background = "transparent_image.png" self.background_color = [1/3,1/3,1/3,0.8] self.auto_dismiss = False self.size_hint = (None,None) self.size = (150,50) self.timer_countdown = MDLabel(font_style = 'H1', theme_text_color = 'Primary', text = str(self.number), halign = 'center', text_color = (1,1,1,1), size_hint_y = None) self.add_widget(self.timer_countdown) def decrement_time(self, dt): self.number -= 1 # self.timer_countdown.text = str(self.number) def on_number(self, instance, value): self.timer_countdown.text = str(value) def start(self,*args): self.t = Clock.schedule_interval(self.decrement_time, 1) def stop(self): Clock.unschedule(self.t) 的引用将保留在MDLabel中,并且只要self.timer_countdown发生更改,on_number()方法就会被执行,并且只会更新number。请注意,您也可以通过取消注释以下行来进行更新:

MDLabel

在这种情况下,# self.timer_countdown.text = str(self.number) 不必是number,也不需要Property方法。