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
CodePudding user response:
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