from tkinter import * import datetime import pytz from math import * from R2Graph import * def main(): root = Tk() root.title("Analog Clock") root.geometry("500x500") panel = Frame(root) panel.pack(side=TOP, fill=X) drawArea = Canvas(root, bg="silver") drawArea.pack(side=TOP, expand=True, fill=BOTH) tzNumber = IntVar() def onChangeTimezone(): # print("tzNumber =", tzNumber.get()) redraw() radionButtonLocal = Radiobutton( panel, text="Local time", variable=tzNumber, value=0, command=onChangeTimezone ) radionButtonLocal.pack(side=LEFT, padx=4, pady=4) radionButtonMoscow = Radiobutton( panel, text="Moscow", variable=tzNumber, value=1, command=onChangeTimezone ) radionButtonMoscow.pack(side=LEFT, padx=4, pady=4) radionButtonDushanbe = Radiobutton( panel, text="Dushanbe", variable=tzNumber, value=2, command=onChangeTimezone ) radionButtonDushanbe.pack(side=LEFT, padx=4, pady=4) tzNumber.set(0) tzMoscow = pytz.timezone("Europe/Moscow") tzDushanbe = pytz.timezone("Asia/Dushanbe") idHourHand = 0 idMinuteHand = 0 idSecondHand = 0 margin = 0.1 ex = R2Vector(250.*(1.-margin), 0.) ey = R2Vector(0., -250.*(1.-margin)) center = R2Point(250., 250.) rHour = 0.5; wHour = 0.04 rMinute = 0.7; wMinute = 0.025 rSecond = 0.9; wSecond = 0.015 tzMoscow = pytz.timezone("Europe/Moscow") tzDushanbe = pytz.timezone("Asia/Dushanbe") def drawFace(): w = drawArea.winfo_width() h = drawArea.winfo_height() center.x = w/2.; center.y = h/2. ex.x = w/2.*(1.-margin) ey.y = -h/2.*(1.-margin) leftTop = center - ex + ey rightBottom = center + ex - ey drawArea.create_oval( leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, fill="white", outline="black", width=4 ) for i in range(60): angle = pi/2. - i*(2.*pi/60.) r = 0.95; tickW = 3 if i%5 == 0: r = 0.9; tickW = 5 v = ex*cos(angle) + ey*sin(angle) p0 = center + v*r p1 = center + v drawArea.create_line( (p0.x, p0.y), (p1.x, p1.y), fill="black", width=tickW ) if i%5 == 0: # Draw minute numbers m = 12 if i == 0 else i//5 txt = str(m) p3 = center + v*0.75 drawArea.create_text( p3.x, p3.y, text=txt, font=("Times", 32) ) def drawHand(v, n, color): t = [] t.append(center - v*0.2) t.append(center - n) t.append(center + v) t.append(center + n) p = [ (pnt.x, pnt.y) for pnt in t ] idHand = drawArea.create_polygon( p, fill=color, outline=color ) return idHand def drawHands(): nonlocal idHourHand, idMinuteHand, idSecondHand # Erase old hands if idHourHand != 0: drawArea.delete(idHourHand) if idMinuteHand != 0: drawArea.delete(idMinuteHand) if idSecondHand != 0: drawArea.delete(idSecondHand) tzNum = tzNumber.get() if tzNum == 1: dt = datetime.datetime.now(tz=tzMoscow) elif tzNum == 2: dt = datetime.datetime.now(tz=tzDushanbe) else: dt = datetime.datetime.now() # Draw hour hand angle_cw = ( (2.*pi/12.)*dt.hour + ((2.*pi/12.)/60.)*dt.minute + ((2.*pi/12.)/3600.)*dt.second ) angle = pi/2. - angle_cw v = ex*cos(angle) + ey*sin(angle) n = v.normal() idHourHand = drawHand(v*rHour, n*wHour, "darkBlue") # Draw minute hand angle_cw = ( ((2.*pi)/60.)*dt.minute + ((2.*pi)/3600.)*dt.second ) angle = pi/2. - angle_cw v = ex*cos(angle) + ey*sin(angle) n = v.normal() idMinuteHand = drawHand(v*rMinute, n*wMinute, "darkGreen") # Draw minute hand angle_cw = ( ((2.*pi)/60.)*dt.second ) angle = pi/2. - angle_cw v = ex*cos(angle) + ey*sin(angle) n = v.normal() idSecondHand = drawHand(v*rSecond, n*wSecond, "red") def redraw(): drawArea.delete("all") idHourHand = 0 idMinuteHand = 0 idSecondHand = 0 drawFace() drawHands() drawArea.bind("", lambda e: redraw()) def animate(): drawHands() drawArea.after(1000, animate) root.update() drawArea.after(100, animate) # Start animation root.mainloop() if __name__ == "__main__": main()