Как обновлять Canvas каждую секунду?

#python #python-3.x #kivy

#python #python-3.x #kivy

Вопрос:

Я пытаюсь создать часы с 3 дугами, по одной для часов, минут и секунд. В настоящее время приложение рисует каждую из дуг разными цветами и радиусами, как и ожидалось. Дуги также заполняются в зависимости от времени запуска приложения. Красная дуга представляет часы, зеленая дуга представляет минуты, а синяя дуга представляет секунды. Отсюда я пытаюсь обновить canvas так, чтобы дуги менялись в зависимости от времени (раз в секунду). Я также хотел бы метку, которая отображает время в центре часов. Кто-нибудь может мне помочь с этой проблемой? Я относительно новичок в Kivy, поэтому не совсем уверен, что мне следует делать.

 from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Line
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from datetime import datetime

# update canvas every second
# display time in center of clock
class drawClock(FloatLayout):

    def __init__(self, **kwargs):
        super(drawClock, self).__init__(**kwargs)
        self.bind(pos=self.updateClock)
        self.bind(size=self.updateClock)

    def updateClock(self, *kwargs):
        with self.canvas:
            now = datetime.now()
            hour = now.hour
            minute = now.minute
            second = now.second
            hourAngle = (hour%12) * 30
            minuteAngle = minute * 6
            secondAngle = second * 6
            Line(circle = (self.center_x, self.center_y, 80, 0, hourAngle), width = 2, color = Color(1,0,0))
            Line(circle = (self.center_x, self.center_y, 65, 0, minuteAngle), width = 2, color = Color(0,1,0))
            Line(circle = (self.center_x, self.center_y, 50, 0, secondAngle), width = 2, color = Color(0,0,1))

class mainApp(App):
    def build(self):
        return drawClock()

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

Ответ №1:

Вы должны использовать Clock.schedule_interval() для обновления рисунка, но вместо создания новых строк вы должны повторно использовать их, чтобы сэкономить ресурсы:

 from kivy.app import App
from kivy.graphics import Color, Line
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from datetime import datetime

class drawClock(FloatLayout):
    def __init__(self, **kwargs):
        super(drawClock, self).__init__(**kwargs)
        self.bind(pos=self.updateClock)
        self.bind(size=self.updateClock)
        Clock.schedule_interval(self.updateClock, 1)
        self.create_canvas()

    def create_canvas(self):
        with self.canvas:
            self.hour_line = Line(width = 2, color = Color(1,0,0))
            self.minute_line =  Line(width = 2, color = Color(0,1,0))
            self.second_line = Line(width = 2, color = Color(0,0,1))

    def updateClock(self, *kwargs):
        now = datetime.now()
        hour = now.hour
        minute = now.minute
        second = now.second
        hourAngle = (hour%12) * 30
        minuteAngle = minute * 6
        secondAngle = second * 6
        self.hour_line.circle = self.center_x, self.center_y, 80, 0, hourAngle
        self.minute_line.circle = self.center_x, self.center_y, 65, 0, minuteAngle
        self.second_line.circle = self.center_x, self.center_y, 50, 0, secondAngle


class mainApp(App):
    def build(self):
        return drawClock()

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

Ответ №2:

Используйте update() метод. Это грубый способ, но он даст вам то, что вы хотите. Метод update в основном обновляет окно.

Более эффективный способ сделать это — использовать after() метод.

After в основном говорит, что делать после, так что разберитесь с этим.

window.after(delay_ms, callback=None, *args)

Это параметры для after() .

Например, это означало бы подождать одну секунду, а затем выполнить func up

window.after(1000, up)