Tkinter: How to make Tkinter to refresh and delete last lines?

早过忘川 提交于 2020-01-21 14:38:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!