代码之家  ›  专栏  ›  技术社区  ›  phchen2

Kivy Clockschedule.interval()的回调()执行问题

  •  0
  • phchen2  · 技术社区  · 2 年前

    我不确定问题标题是否合适,我的问题是,当我使用Kivy Clock.schedule.interval(callback,0)运行时间倒计时代码时,在完成时间倒计时后的回调函数中,它可能不会显示新的设置倒计时值。我的代码如下

    1. 在每次运行的回调中,倒计时值(tm)将减少dt(从Clock.prschedule.interval()获取)
    2. 当倒计时值小于零(tm<=0)时,将倒计时值重置为初始值
    3. 为了检查重置的倒计时值,我使用print()来显示倒计时值。它显示正确的值
    4. 要设置ObjectProperty,请将倒计时值传递到.kv文件并在标签中显示倒计时值
    5. 标签总是在倒计时完成之前显示正确的倒计时值。
    6. 当倒计时完成时,它会将倒计时值重置为初始值,在重新开始倒计时之前,我使用for循环来延迟倒计时重新开始
    7. 在延迟持续时间内,标签总是将倒计时值显示为零

    我的问题是,为什么在延迟持续时间内,标签总是将其值(文本)显示为零,我应该已经将倒计时值重置为其初始值。

    我的代码如下, 在.py文件中

    from kivy.app import App
    from kivy.clock import Clock
    from kivy.properties import ObjectProperty
    from kivy.uix.tabbedpanel import TabbedPanel
    from kivy.uix.boxlayout import BoxLayout
    from time import strftime
    
    class Test(TabbedPanel):
        pass
    
    class ClockTest(BoxLayout):    
        time_str = ObjectProperty()
        tm_interval = 5     # 5 seconds
        tm_flag = True
        tm = tm_interval
    
        def __init__(self, **kwargs):
            super(ClockTest, self).__init__(**kwargs)
            Clock.schedule_interval(self.cb, 0)
            
        def cb(self, dt):
            if self.tm_flag:
                self.tm -= dt
                if self.tm <= 0:
                    self.tm = self.tm_interval          
                    print('tm: ', self.tm)
                    m, s = divmod(self.tm, 60)
                    self.time_str.text = ('%02d:%02d.%02d' %
                        (int(m), int(s), int(s * 100 % 100)))
                    print('time_str: ',self.time_str.text)
                
                    # loop: for time delay 
                    for x in range(100000):
                        text = strftime('[b]%H[/b]:%M:%S')
    
            m, s = divmod(self.tm, 60)
            self.time_str.text = ('%02d:%02d.%02d' %
                (int(m), int(s), int(s * 100 % 100)))
        
        
    class ClockTest1App(App):
        def build(self):
            tm_obj = Test()
        
            return tm_obj
    
    if __name__ == '__main__':
        ClockTest1App().run()
    

    在.kv文件中

    #:kivy 2.1.0
    
    Test:
    
    <ClockTest>:
        time_str: time_str
    
        orientation: 'vertical'
    
        Label:
            id: time_str
            font_size: 40
            bold: True
            text: time_str.text 
    
    <Test>:    
        do_default_tab: False
    
        TabbedPanelItem:
            text: 'ClockTest'
            font_size: 15
            ClockTest:
    

    在代码中它不应该有逻辑问题,我不知道是什么问题,请帮我解决,谢谢!

    另一个问题是,我如何改进时间延迟代码,如果使用时间睡眠,它会阻塞代码并显示黑屏。

    0 回复  |  直到 2 年前
        1
  •  0
  •   phchen2    2 年前

    事实上,在这个问题上,我有两个问题:

    1. 当我想使用“for loop”在短时间内显示重置时间值时,为什么它总是在循环运行过程中显示最后一个时间值-零值(在时间重置之前)?
    2. 如何再次显示时间倒计时前一段时间内的重置时间值?

    现在我可以解决第二个问题,但我仍然不知道为什么“for循环”延迟代码不起作用。

    为了再次显示时间倒计时前一段时间内的重置时间值,我更新了.py文件,如下所示,

    from kivy.app import App
    from kivy.clock import Clock
    from kivy.properties import ObjectProperty
    from kivy.uix.tabbedpanel import TabbedPanel
    from kivy.uix.boxlayout import BoxLayout
    from time import strftime
    
    class Test(TabbedPanel):
        pass
    
    class ClockTest(BoxLayout):    
        time_str = ObjectProperty()
        tm_interval = 5     # 5 seconds
        tm_flag = True
        tm = tm_interval
    
        def __init__(self, **kwargs):
            super(ClockTest, self).__init__(**kwargs)
            Clock.schedule_interval(self.cb, 0)
        
        def delayset(self, cb, dt):
            Clock.schedule_once(cb, dt)
            
        def delaycb(self, dt):
            self.tm_flag = True
        
        def cb(self, dt):
            if self.tm_flag:
                self.tm -= dt
                if self.tm <= 0:
                    self.tm = self.tm_interval          
                    print('tm: ', self.tm)
                    self.tm_flag = False
                    self.delayset(self.delaycb, 3)                
                
            m, s = divmod(self.tm, 60)
            self.time_str.text = ('%02d:%02d.%02d' %
                (int(m), int(s), int(s * 100 % 100)))
    
    
    class ClockTest1App(App):
        def build(self):
            tm_obj = Test()
            return tm_obj
    
    if __name__ == '__main__':
        ClockTest1App().run()