[Tutor] Simple Tkinter question

Alan Gauld alan.gauld at freenet.co.uk
Fri Oct 7 10:26:07 CEST 2005

> def my_update():
>   for i in range(3):
>     tv.set("Now it's %d"%i)
>     sleep(1)
> Button(text="Update", command=my_update).pack()
> root.mainloop()
> What happens when I hit the Update button is a 3-second pause, then "Now 
> it's 2" is displayed.

This is a common gotcha in GUI programming.

The function executes but the GUI doesn't redraw itself on the screen until 
function completes. Normally there is a GUI  function you can call to force
a redraw (or repaint or refresh) of the screeen before each sleep which
should fix this. Unfortunately I can't see one for Tkinter.

Another approach is to use a timer which creates its own events and catch
them in your original function rather than using a loop, thus you change the 
in the field and create a one second timer calling yourself, repeat the 
until the value is where you want and stop creating timers!

Finally you can bypass the timer by sending an event to yourself which is 
associated with your callback, so after each sleep you post an event.

But the simplest solution if you can find the function is to simply force a
redraw after each loop iteration.

There is a downside to this approach which may be why Tkinter doesn't
appear to support it - if your function had a long loop the user would lose
control of the application while the metod executed - you effctively make
the app modal, which is "A Bad Thing". Thats why GUI purists prefer the
timer/event techniques described above.


Alan G
Author of the learn to program web tutor

More information about the Tutor mailing list