首页 > 解决方案 > 如何使用kivy每分钟调用一个函数?

问题描述

当我按下一个按钮时,我想每分钟运行一个功能。我正在使用sched.scheduler,但我的 kivy 应用程序崩溃了。

s.enter(60, 1, self.graph_data, (s,))
s.run()

有人可以帮助我吗?

标签: pythonpython-3.xkivy

解决方案


您可以使用kivy 提供的 Clock 对象

import kivy

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
    
class TestApp(App):
    
    def build(self):
        self.timer = None
        btn1 = Button(text='Click to start')
        btn1.bind(state=self.callbackStart)
        btn2 = Button(text='Click to stop')
        btn2.bind(state=self.callbackStop)

        bl = BoxLayout()
        bl.add_widget(btn1)
        bl.add_widget(btn2)
        return bl

    def callbackStart(self, instance, value):
        print('My button1 <%s> state is <%s>' % (instance, value))
        if self.timer is not None:
            Clock.unschedule(self.timer)
        self.timer = Clock.schedule_interval(self.timedAction, 0.5)        

    def callbackStop(self, instance, value):
        print('My button2 <%s> state is <%s>' % (instance, value))
        Clock.unschedule(self.timer)


    def timedAction(self, dt):
        print("Repeat")

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

您还应该能够通过使用带有 Thread 和 Event 对象的 threading 内置模块来执行此类操作。

import kivy

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout

import threading


class MyTimedAction(threading.Thread):
    def __init__(self, event):
        threading.Thread.__init__(self)
        self.stopped = event

    def run(self):
        while not self.stopped.wait(0.5):
            print("Periodic action performed")


class TestApp(App):
    
    def build(self):
        # Create the stopTimer event. Initialize as stopped.
        self.stopTimer = threading.Event()
        self.stopTimer.set()

        btn1 = Button(text='Click to start')
        btn1.bind(state=self.callbackStart)
        btn2 = Button(text='Click to stop')
        btn2.bind(state=self.callbackStop)

        bl = BoxLayout()
        bl.add_widget(btn1)
        bl.add_widget(btn2)
        return bl

    def callbackStart(self, instance, value):
        print('My button1 <%s> state is <%s>' % (instance, value))
        if self.stopTimer.isSet():  # (Eventually) avoid duplicates if timer already started
            self.stopTimer.clear()
            thread = MyTimedAction(self.stopTimer)
            thread.start()

    def callbackStop(self, instance, value):
        print('My button2 <%s> state is <%s>' % (instance, value))
        self.stopTimer.set()

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

上面的示例假设如果计时器已经启动,它不会在新线程上再次启动另一个定时作业。简短的 GUI 代码仅用于演示目的。


推荐阅读