1 #coding=gbk
2 # -*- encoding:utf-8 -*-
3
4 import time,datetime
5 import math
6 import itertools
7 import tkinter
8 import threading
9
10 def get_clock_step(base_pntr,long_pntr):
11 pos = []
12 for i in range(60):
13 pos.append((base_pntr[0]+long_pntr*math.cos(i*math.pi/30),
14 base_pntr[0]+long_pntr*math.sin(i*math.pi/30)))
15 return pos[45:] + pos[:45]
16
17 def gen_i_pos(c_pntr,long_pntr):
18 for i,p in enumerate(get_clock_step(c_pntr,long_pntr)):
19 yield i,p
20
21 class Pointer:
22
23 def __init__(self,c_pntr,long_pntr,cvns,scale=None,super_pntr=None,width=1,fill='black'):
24 # 引數說明:
25 # c_pntr: 錶盤的中心座標;
26 # long_pntr: 錶針長;
27 # cvns: 畫布引用;
28 # scale: 指標行走比例;
29 # super_pntr: 上級指標;
30 # width: 指標粗細;
31 # fill: 指標顏色;
32 self.pos_iter = itertools.cycle(gen_i_pos(c_pntr,long_pntr))
33 self.scale = scale
34 self.cvns = cvns
35 self.crrnt_pos = self.pos_iter.__next__()[1]
36 self.c_pntr = c_pntr
37 self.super_pntr = super_pntr
38 self.id_pntr = None
39 self.width = width
40 self.fill = fill
41
42 def draw(self):
43 self.id_pntr = cvns.create_line(self.c_pntr,self.crrnt_pos,width=self.width,fill=self.fill)
44
45 def walk_step(self):
46 self.delete()
47 self.draw()
48 i,self.crrnt_pos = self.pos_iter.__next__()
49 if self.super_pntr and self.scale and (i + 1) % self.scale == 0:
50 self.super_pntr.walk_step()
51
52 def delete(self):
53 if self.id_pntr:
54 self.cvns.delete(self.id_pntr)
55
56 def set_start(self,steps):
57 for i in range(steps-1):
58 self.pos_iter.__next__()
59 self.crrnt_pos = self.pos_iter.__next__()[1]
60
61 class PlateImg:
62
63 def __init__(self,c_pntr,clock_r,cvns,img):
64 self.cvns = cvns
65 self.clock_r = clock_r
66 self.c_pntr = c_pntr
67 self.img = img
68 self.pid = None
69 self.draw()
70
71 def draw(self):
72 self.im = tkinter.PhotoImage(file=self.img)
73 self.pid = self.cvns.create_image(self.c_pntr,image = self.im)
74
75 def delete(self):
76 if self.pid:
77 self.cvns.delete(self.pid)
78
79 def set_img(self,img):
80 self.img = img
81 self.delete()
82 self.draw()
83
84
85
86 class InImg(PlateImg):
87 def draw(self):
88 x = self.c_pntr[0]
89 y = self.c_pntr[0] + self.clock_r / 5
90 self.im = tkinter.PhotoImage(file=self.img)
91 self.pid = self.cvns.create_image(x,y,image = self.im)
92
93 class CustomPlate:
94 def __init__(self,c_pntr,clock_r,cvns,imgp='platex.gif',imgi='flowersx.gif'):
95 self.pi = PlateImg(c_pntr,clock_r,cvns,imgp)
96 self.ii = InImg(c_pntr,clock_r,cvns,imgi)
97
98 def set_img(self,imgp,imgi):
99 self.pi.set_img(imgp)
100 self.ii.set_img(imgi)
101
102 def delete(self):
103 self.pi.delete()
104 self.ii.delete()
105
106
107 class Plate:
108
109 def __init__(self,c_pntr,clock_r,cvns,long=10):
110 self.pos_a = get_clock_step(c_pntr,clock_r - long)
111 self.pos_b = get_clock_step(c_pntr,clock_r)
112 self.cvns = cvns
113 self.plates = []
114 self.draw()
115
116 def draw(self):
117 for i,p in enumerate(zip(self.pos_a,self.pos_b)):
118 width = 5 if (i + 1) % 5 == 0 else 3
119 pid = self.cvns.create_line(*p,width=width)
120 self.plates.append(pid)
121
122 def delete(self):
123 if self.plates:
124 for item in self.plates:
125 self.cvns.delete(item)
126
127 class MyClock:
128
129 def __init__(self,base_pntr,clock_r,cvns):
130 self.c_pntr = base_pntr
131 self.clock_r = clock_r
132 self.cvns = cvns
133 self.plate = Plate(base_pntr,clock_r,self.cvns)
134 h,m,s = self.start_time()
135 self.h_pntr = Pointer(base_pntr,3 * clock_r // 5,self.cvns,width=5,fill='blue')
136 self.m_pntr = Pointer(base_pntr,4 * clock_r // 5,self.cvns,12,super_pntr=self.h_pntr,width=3,fill='green')
137 self.h_pntr.set_start(h * 5)
138 self.m_pntr.set_start(m)
139 self.h_pntr.walk_step()
140 self.m_pntr.walk_step()
141 self.s_pntr = Pointer(base_pntr,clock_r-5,self.cvns,60,super_pntr=self.m_pntr,fill='red')
142 self.s_pntr.set_start(s)
143
144 def chg_plate(self):
145 self.plate.delete()
146 if isinstance(self.plate,CustomPlate):
147 self.plate = Plate(self.c_pntr,self.clock_r,self.cvns)
148 else:
149 self.plate = CustomPlate(self.c_pntr,self.clock_r,self.cvns)
150 self.h_pntr.delete()
151 self.h_pntr.draw()
152 self.m_pntr.delete()
153 self.m_pntr.draw()
154
155 def set_img(self,imgp,imgi):
156 if not isinstance(self.plate,CustomPlate):
157 self.chg_plate()
158 self.plate.set_img(imgp,imgi)
159
160 def walk_step(self):
161 self.s_pntr.walk_step()
162
163 def start_time(self):
164 crrnt_time = datetime.datetime.now()
165 hour = crrnt_time.hour
166 minute = crrnt_time.minute
167 second = crrnt_time.second
168 return hour,minute,second
169
170 class MyButton:
171 def __init__(self,root,clock):
172 self.clock = clock
173 button = tkinter.Button(root,text = '改變錶盤',command = self.chg_plate)
174 button.pack()
175
176 def chg_plate(self):
177 self.clock.chg_plate()
178
179 class MyTk(tkinter.Tk):
180 def quit(self):
181 StartClock.looping = False
182 self.quit()
183
184 class StartClock:
185 looping = True
186 def __init__(self,mc,root):
187 self.mc = mc
188 self.root = root
189
190 def start_clock(self):
191 while StartClock.looping:
192 self.mc.walk_step()
193 self.root.update()
194 time.sleep(0.05)
195
196 if __name__ == '__main__':
197 root = MyTk()
198 cvns = tkinter.Canvas(root,width=400,height=400,bg='white')
199 cvns.pack()
200 mc = MyClock((200,200),200,cvns)
201 bt = MyButton(root,mc)
202 t = threading.Thread(target=StartClock(mc,root).start_clock)
203 t.setDaemon(True)
204 t.start()
205 root.resizable(False, False)
206 root.mainloop()