Python Tkinter Label redrawing every 10 seconds

后端 未结 2 574
醉话见心
醉话见心 2020-12-06 20:30

I have this following Python Tkinter code which redraw the label every 10 second. My question is , to me it seems like it is drawing the new label over and over again over t

相关标签:
2条回答
  • 2020-12-06 20:35

    The correct way to run a function or update a label in tkinter is to use the after method. This puts an event on the event queue to be executed at some time in the future. If you have a function that does some work, then puts itself back on the event queue, you have created something that will run forever.

    Here's a quick example based on your example:

    import Tkinter as tk
    import time
    
    def Draw():
        global text
    
        frame=tk.Frame(root,width=100,height=100,relief='solid',bd=1)
        frame.place(x=10,y=10)
        text=tk.Label(frame,text='HELLO')
        text.pack()
    
    def Refresher():
        global text
        text.configure(text=time.asctime())
        root.after(1000, Refresher) # every second...
    
    root=tk.Tk()
    Draw()
    Refresher()
    root.mainloop()
    

    There are a lot of things I would change about that program from a coding style point of view, but I wanted to keep it as close to your original question as possible. The point is, you can use after to call a function that updates the label without having to create new labels. Plus, that function can arrange for itself to be called again at some interval. In this example I picked one second just so that the effect is easier to see.

    You also asked "I am wondering what are the general cases that i should not use threading and what are the general cases i could use threading?"

    To put a blunt point on it, you should never use threading if you have to ask a question about when to use threading. Threading is an advanced technique, it is complicated, and it easy to get wrong. It's quite possible for threading to make your program slower rather than faster. It has subtle consequences, such as your programs failing mysteriously if you do things that aren't thread safe.

    To be more specific to your situation: you should avoid using threads with tkinter. You can use them, but you can't access widgets from these other threads. If you need to do something with a widget, you must put an instruction in a thread-safe queue, and then in the main thread you need to periodically check that queue to see if there's an instruction to be processed. There are examples of that on this website if you search for them.

    If all that sounds complicated, it is. For most of the GUIs you write, you won't need to worry about that. If you can take large processes and break them down into chunks that execute in 100 ms or less, you only need after, and never need threads.

    0 讨论(0)
  • 2020-12-06 20:57

    To allow the cleanup with minimal code changes, you could pass previous frames explicitly:

    import Tkinter as tk
    
    def Draw(oldframe=None):
        frame = tk.Frame(root,width=100,height=100,relief='solid',bd=1)
        frame.place(x=10,y=10)
        tk.Label(frame, text='HELLO').pack()
        frame.pack()
        if oldframe is not None:
            oldframe.destroy() # cleanup
        return frame
    
    def Refresher(frame=None):
        print 'refreshing'
        frame = Draw(frame)
        frame.after(10000, Refresher, frame) # refresh in 10 seconds
    
    root = tk.Tk()
    Refresher()
    root.mainloop()
    
    0 讨论(0)
提交回复
热议问题