简体   繁体   中英

Displaying multiple clocks simultaneously with Kivy

Using Kivy 2.0.0 and Python 2.9.9

Just started learning Kivy and I'm trying to display three custom clocks simultaneously (using the current time for now). Ideally, I want to be able to get the three clocks to be assignable to locations in a GridLayout or BoxLayout but for now I just want to be able to display three clocks at the same time.

I've tried modifying the kv file to nest multiple iterations of my clock in a GridLayout and I've tried splitting them up over several kv files and building each one individually from the python side. It always either draws the clocks on top of each other or gives me an error.

Direction and advice is much appreciated. Thank you in advance.

I modified this code to produce the following Python Code for my clock:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Line
from kivy.uix.floatlayout import FloatLayout
from math import cos, sin, pi
from kivy.clock import Clock
from kivy.lang import Builder
import os

from datetime import datetime

Builder.load_file(os.path.dirname(os.path.realpath(__file__)) + "\\clock.kv")

class MyClockWidget(FloatLayout):
    pass

class Ticks(Widget):
    def __init__(self, **kwargs):
        super(Ticks, self).__init__(**kwargs)
        self.bind(pos=self.update_clock)
        self.bind(size=self.update_clock)

    def update_clock(self, *args):
        self.canvas.clear()
        with self.canvas:
            time = datetime.now()
            
            for s in range(0, time.second+1):

                if s < 30:
                    Color(125.0/255.0, 253.0/255.0, 254.0/255.0)
                elif s >= 30 and s < 45:
                    Color(255.0/255.0, 95.0/255.0, 31.0/255.0)
                else:
                    Color(255.0/255.0, 49.0/255.0, 49.0/255.0)
                
                Line(points = [
                    self.center_x + 0.5*self.r*sin(pi/60*s - pi/2), 
                    self.center_y + 0.5*self.r*cos(pi/60*s - pi/2), 
                    self.center_x + 0.795*self.r*sin(pi/60*s - pi/2), 
                    self.center_y + 0.795*self.r*cos(pi/60*s - pi/2)
                    ], 
                width=2, 
                cap="none"
                )

            for m in range(0, time.minute + 1):
                Color(125.0/255.0, 253.0/255.0, 254.0/255.0)
                Line(points = [
                    self.center_x + 0.3*self.r*sin(pi/60*m - pi/2), 
                    self.center_y + 0.3*self.r*cos(pi/60*m - pi/2), 
                    self.center_x + 0.495*self.r*sin(pi/60*m - pi/2), 
                    self.center_y + 0.495*self.r*cos(pi/60*m - pi/2)
                    ], 
                width=2, 
                cap="none"
                )
            
            
            if time.hour < 12:
                hr = time.hour
            else:
                hr = time.hour - 12

            for h in range(0, hr + 1):

                Color(125.0/255.0, 253.0/255.0, 254.0/255.0)
                Line(points = [
                    self.center_x + 0.2*self.r*sin(pi/12*h - pi/2), 
                    self.center_y + 0.2*self.r*cos(pi/12*h - pi/2), 
                    self.center_x + 0.295*self.r*sin(pi/12*h - pi/2), 
                    self.center_y + 0.295*self.r*cos(pi/12*h - pi/2)
                    ], 
                width=2, 
                cap="none"
                )

            th = h*60 + time.minute
            Color(125.0/255.0, 253.0/255.0, 254.0/255.0)
            Line(points=[self.center_x + 0.2*self.r*sin(pi/720*th - pi/2), self.center_y + 0.2*self.r*cos(pi/720*th - pi/2), self.center_x + 0.295*self.r*sin(pi/720*th - pi/2), self.center_y + 0.295*self.r*cos(pi/720*th - pi/2)], width=2, cap="none")


class MyDashApp(App):
    def build(self):
        clock = MyClockWidget()
        Clock.schedule_interval(clock.ticks.update_clock, 0.1)
        return clock

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

and this kv file:

#:kivy 2.0.0

#:import math math

<ClockNumber@Label>:
    i: 0
    text: str(self.i)
    pos_hint: {"center_x": 0.5+0.42*math.sin(math.pi/12*(self.i-12) + math.pi/2), "center_y": 0.5+0.42*math.cos(math.pi/12*(self.i-12) + math.pi/2)}
    font_size: self.height/16
    color: 125.0/255.0, 253.0/255.0, 254.0/255.0

<MyClockWidget>:
    face: face
    ticks: ticks
    FloatLayout:
        id: face
        size_hint: None, None
        pos_hint: {"center_x":0.5, "center_y":0.5}
        size: 0.9*min(root.size), 0.9*min(root.size)

        ClockNumber:
            i: 0        
        ClockNumber:
            i: 1
        ClockNumber:
            i: 2
        ClockNumber:
            i: 3
        ClockNumber:
            i: 4
        ClockNumber:
            i: 5
        ClockNumber:
            i: 6
        ClockNumber:
            i: 7
        ClockNumber:
            i: 8
        ClockNumber:
            i: 9
        ClockNumber:
            i: 10
        ClockNumber:
            i: 11
        ClockNumber:
            i: 12
    
    Ticks:
        id: ticks
        r: min(root.size)*0.9/2

You code is almost working. I think the main problem is that your Ticks widget in the kv needs its position set. Try changing that in the kv to:

Ticks:
    id: ticks
    pos_hint: face.pos_hint
    r: min(root.size)*0.9/2

And I got three clocks to appear and update like this:

class MyDashApp(App):
    def build(self):
        root = GridLayout(cols=3)
        for _i in range(3):
            clock = MyClockWidget()
            Clock.schedule_interval(clock.ticks.update_clock, 0.1)
            root.add_widget(clock)
        return root

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM