问题
Problem is: Clock hands in Tkinter flashes because I use w.delete
, but if i don't use it then clock hands duplicate.. Please help.
import Tkinter as tk; import time
from math import cos,sin,pi
import sys
root=tk.Tk(); root.title("Clock")
w = tk.Canvas(root, width=320, height=320, bg="#456", relief= "sunken", border=10)
w.pack()
size=300
def funA():
s=time.localtime()[5]
m=time.localtime()[4]
h=time.localtime()[3]
w.update()
degrees = 6*s
angle = degrees*pi*2/360
ox = 165
oy = 165
x = ox + size*sin(angle)*0.45
y = oy - size*cos(angle)*0.45
t = w.create_line(ox,oy,x,y, fill = "#ffc")
degrees1 = 6*m
angle1 = degrees1*pi*2/360
ox1 = 165
oy1 = 165
x1 = ox1 + size*sin(angle1)*0.4
y1 = oy1 - size*cos(angle1)*0.4
t1 = w.create_line(ox1,oy1,x1,y1, fill = "Red", width=6)
degrees2 = 30*h
angle2 = degrees2*pi*2/360
ox2 = 165
oy2 = 165
x2 = ox2 + size*sin(angle2)*0.2
y2 = oy2 - size*cos(angle2)*0.2
t2 = w.create_line(ox2,oy2,x2,y2, fill = "Black", width=8)
w.update()
root.after(200,funA)
w.delete(t1)
root.after(1500, funA)
uzr1 = tk.Label(root, text="12", bg="#456" )
uzr1.place(x=160, y=13)
uzr2 = tk.Label(root, text="6", bg="#456" )
uzr2.place(x=160, y=303)
uzr3 = tk.Label(root, text="3", bg="#456" )
uzr3.place(x=310, y=160)
uzr4 = tk.Label(root, text="9", bg="#456" )
uzr4.place(x=11, y=160)
def Quit():
root.after(700,root.destroy())
e = tk.Button(root,text="Quit", command=Quit)
e.pack()
root.mainloop()
If i write in funA
, w.delete(t)
, then Clock second-hand is flashing, if not then its duplicating.. So it is with all clock hands..
- t is Second hand
- t1 is Minute hand
- t2 is Hour hand
Hoping to receive fast useful reply
回答1:
There are a few things here that need fixing. For one, you don't need to call update
. Generally speaking you should never call it, though that rule can be broken once you understand why that rule exists. It's safe to call update_idletasks
which is generally what you want if you feel the need to call update
. Even that can be avoided with proper design.
Second, there is no need to delete the line and create a new line. The canvas widget has a method named coords
which can be used to adjust the coordinates of an item.
Third, you can leverage the tagging feature of the canvas. Give each clock hand a tag with a suitable name (eg: "second", "minute", "hour") and you use that to tell the canvas which item to update.
Finally, get in the habit of either creating an application class, or putting your application code in a function. It makes it easier to solve the problem of not being able to call a function until it is defined, and makes it so that you don't have to use global variables.
Here is a working example:
import Tkinter as tk; import time
from math import cos,sin,pi
import sys
class MyApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.size=300
self.title("Clock")
self.w = tk.Canvas(self, width=320, height=320, bg="#456", relief= "sunken", border=10)
self.w.pack()
self.w.create_line(0,0,0,0, fill="#ffc", tags="hour")
self.w.create_line(0,0,0,0, fill="red", tags="minute")
self.w.create_line(0,0,0,0, fill="black", tags="second")
uzr1 = tk.Label(self, text="12", bg="#456" )
uzr1.place(x=160, y=13)
uzr2 = tk.Label(self, text="6", bg="#456" )
uzr2.place(x=160, y=303)
uzr3 = tk.Label(self, text="3", bg="#456" )
uzr3.place(x=310, y=160)
uzr4 = tk.Label(self, text="9", bg="#456" )
uzr4.place(x=11, y=160)
e = tk.Button(self,text="Quit", command=self.Quit)
e.pack()
self.update_clock()
def update_clock(self):
s=time.localtime()[5]
m=time.localtime()[4]
h=time.localtime()[3]
degrees = 6*s
angle = degrees*pi*2/360
ox = 165
oy = 165
x = ox + self.size*sin(angle)*0.45
y = oy - self.size*cos(angle)*0.45
self.w.coords("hour", (ox,oy,x,y))
degrees1 = 6*m
angle1 = degrees1*pi*2/360
ox1 = 165
oy1 = 165
x1 = ox1 + self.size*sin(angle1)*0.4
y1 = oy1 - self.size*cos(angle1)*0.4
self.w.coords("minute", (ox1,oy1,x1,y1))
degrees2 = 30*h
angle2 = degrees2*pi*2/360
ox2 = 165
oy2 = 165
x2 = ox2 + self.size*sin(angle2)*0.2
y2 = oy2 - self.size*cos(angle2)*0.2
self.w.coords("second",(ox2,oy2,x2,y2))
self.after(1000, self.update_clock)
def Quit(self):
self.after(700,self.destroy())
app = MyApp()
app.mainloop()
来源:https://stackoverflow.com/questions/6161816/tkinter-how-to-make-tkinter-to-refresh-and-delete-last-lines