3

Hello I just wanted that the Label change/refresh during the loop, but it doesn't work

This my code

fen1 = Tk()

v = StringVar()
Label(fen1,textvariable=v).pack()

i=0

while(1):
    i=i+1
    v.set(i)
fen1.mainloop() 

Thanks

2 Answers 2

14

here, try this:

from Tkinter import *
import time
root=Tk()

variable=StringVar()

def update_label():
    i=0
    while 1:
        i=i+1
        variable.set(str(i))
        root.update()

your_label=Label(root,textvariable=variable)
your_label.pack()
start_button=Button(root,text="start",command=update_label)
start_button.pack()
root.mainloop()

That should give you a good example. However, it is important to note that during the while loop, you MUST call root.update() otherwise your GUI will freeze until the loop completes (in this case it never does) and never show your numbers.

Also note that you can call update_label() from anywhere in your program. I just added it to the start button for example purposes.

What was wrong with your code was that you had set the while loop free-floating and most importantly before your GUI's mainloop. When you do this, since this loop is infinate, it never allows Tkinter to start its mainloop(). However, if you were to put the while loop after the mainloop, then that would never be executed until after you exit the GUI, this is because the mainloop is infinate until it is stopped (closing the GUI).

So to fix this you simply put it in a function and call it later on during Tkinter's mainloop. You can do this various ways as well, for example, you can use .after() to perform a specific task after a certain amount of time, or make it the command of a button to be run when pressed, ect., ect. .

However, The proper code you should use is the following, as you do not really want infinate loops in your code (other then you mainloop).:

class App (object):
    def __init__(self):
        self.root=Tk()
        self.variable=StringVar()
        self.i=0
        self.your_label=Label(self.root,textvariable=self.variable)
    def grid(self):
        self.your_label.pack()
    def update_label(self):
        self.i=self.i+1
        self.variable.set(str(self.i))
        self.root.after(20,self.update_label)
    def run(self):
        self.grid()
        self.root.after(20,self.update_label)
        self.root.mainloop()

if __name__=='__main__':
    App().run()
Sign up to request clarification or add additional context in comments.

6 Comments

-1: you should never call sleep in the main thread of a GUI. Doing so in an answer sets a bad example. You are wrong when you say that by calling update this never freezes. While the sleep is active, the UI will be frozen, even if only for half a second.
@BryanOakley Ok i changed that.
It's still not the right solution. In addition to not calling sleep, as a rule of thumb you shouldn't have infinite loops either. To update a label every half second you should take advantage of the event loop and use after
I was answering as close as the OP's code as i could. i can add that to my answer aswell though :)
@BryanOakley There, i added it.
|
0

Your code never gets to the mainloop. In order to see something like this, you need to bind the update in a callback which gets called in the mainloop (indirectly, through events).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.