A very simple tkinter analog stopclock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #!/usr/bin/python
#stopclock.py By Prashanth Chengi (prashanth.chengi@gmail.com)
#Based on clock.py by Anton Vredegoor (anton.vredegoor@gmail.com)
#The original program was an analog clock. I modified it into a stopclock, much like a chess clock.
# last edit: March 2013
# license: GPLv3
# enjoy!
"""
A very simple clock.
The program transforms worldcoordinates into screencoordinates
and vice versa according to an algorithm found in: "Programming
principles in computer graphics" by Leendert Ammeraal.
"""
from Tkinter import *
from time import localtime
from datetime import timedelta,datetime
from math import sin, cos, pi
import sys, types, os, time
_inidle = type(sys.stdin) == types.InstanceType and \
sys.stdin.__class__.__name__ == 'PyShell'
class transformer:
def __init__(self, world, viewport):
self.world = world
self.viewport = viewport
def point(self, x, y):
x_min, y_min, x_max, y_max = self.world
X_min, Y_min, X_max, Y_max = self.viewport
f_x = float(X_max-X_min) /float(x_max-x_min)
f_y = float(Y_max-Y_min) / float(y_max-y_min)
f = min(f_x,f_y)
x_c = 0.5 * (x_min + x_max)
y_c = 0.5 * (y_min + y_max)
X_c = 0.5 * (X_min + X_max)
Y_c = 0.5 * (Y_min + Y_max)
c_1 = X_c - f * x_c
c_2 = Y_c - f * y_c
X = f * x + c_1
Y = f * y + c_2
return X , Y
def twopoints(self,x1,y1,x2,y2):
return self.point(x1,y1),self.point(x2,y2)
class clock:
def __init__(self,root,deltahours = 0):
self.world = [-1,-1,1,1]
self.bgcolor = '#000000'
self.circlecolor = '#808080'
self.timecolor = '#ffffff'
self.circlesize = 0.09
self._ALL = 'all'
self.pad = 25
self.root = root
self.togstate = 0
self.firstrun = 1
self.oldtime = datetime.strptime("01","%d")
self.newtime = datetime.strptime("01","%d")
self.ootime = datetime.strptime("01","%d")
self.ontime = datetime.strptime("01","%d")
self.tdelta = timedelta(0)
WIDTH, HEIGHT = 400, 400
root.bind("<Escape>", lambda _ : root.destroy())
root.bind("<Button-1>", lambda _ : self.stopstartpoll())
self.delta = timedelta(hours = deltahours)
self.canvas = Canvas(root,
width = WIDTH,
height = HEIGHT,
background = self.bgcolor)
viewport = (self.pad,self.pad,WIDTH-self.pad,HEIGHT-self.pad)
self.T = transformer(self.world,viewport)
self.root.title('Clock')
self.canvas.bind("<Configure>",self.configure())
self.canvas.pack(fill=BOTH, expand=YES)
self.poll()
def stopstartpoll(self):
if self.togstate == 0:
self.togstate = 1
self.ontime = datetime.now()
self.ootime = self.ontime
self.pollid=self.root.after(200,self.poll)
else:
self.togstate = 0
self.root.after_cancel(self.pollid)
def configure(self):
self.redraw()
def redraw(self):
sc = self.canvas
sc.delete(self._ALL)
width = sc.winfo_width()
height =sc.winfo_height()
sc.create_rectangle([[0,0],[width,height]],
fill = self.bgcolor, tag = self._ALL)
viewport = (self.pad,self.pad,width-self.pad,height-self.pad)
self.T = transformer(self.world,viewport)
self.paintgrafics()
def paintgrafics(self):
start = -pi/2
step = pi/6
for i in range(12):
angle = start+i*step
x, y = cos(angle),sin(angle)
self.paintcircle(x,y)
self.painthms()
self.paintcircle(0,0)
def painthms(self):
#T = datetime.timetuple(datetime.utcnow()-self.delta)
if self.togstate == 0:
T = datetime.timetuple(self.oldtime)
else:
self.newtime=self.oldtime+self.tdelta
self.oldtime=self.newtime
T = datetime.timetuple(self.newtime)
x,x,x,h,m,s,x,x,x = T
self.root.title('%02i:%02i:%02i' %(h,m,s))
angle = -pi/2 + (pi/6)*h + (pi/6)*(m/60.0)
x, y = cos(angle)*.60,sin(angle)*.60
scl = self.canvas.create_line
scl(apply(self.T.twopoints,[0,0,x,y]), fill = self.timecolor,
tag =self._ALL, width = 6)
angle = -pi/2 + (pi/30)*m + (pi/30)*(s/60.0)
x, y = cos(angle)*.80,sin(angle)*.80
scl(apply(self.T.twopoints,[0,0,x,y]), fill = self.timecolor,
tag =self._ALL, width = 3)
angle = -pi/2 + (pi/30)*s
x, y = cos(angle)*.95,sin(angle)*.95
scl(apply(self.T.twopoints, [0,0,x,y]), fill = self.timecolor,
tag =self._ALL, arrow = 'last')
def paintcircle(self,x,y):
ss = self.circlesize / 2.0
mybbox = [-ss+x,-ss+y,ss+x,ss+y]
sco = self.canvas.create_oval
sco(apply(self.T.twopoints,mybbox), fill = self.circlecolor,
tag =self._ALL)
def poll(self):
if self.togstate == 0:
self.tdelta = timedelta(0)
else:
self.tdelta = self.ontime - self.ootime
self.configure()
if self.togstate == 1:
self.ootime = self.ontime
self.ontime = datetime.now()
self.pollid=self.root.after(200,self.poll)
else:
if self.firstrun==1:
self.firstrun=0
self.pollid=self.root.after(200,self.poll)
def main():
root= Tk()
clock(root,deltahours = -1)
if not _inidle:
root.mainloop()
if __name__=='__main__':
main()
|
This is based on Anton Vredegoor's analog clock program (http://code.activestate.com/recipes/576830-analog-clock/ ) I have changed it from an analog clock to an analog stop clock. The clock starts when you left click on it and stops again if you click again.