[Tutor] Simple Tkinter question

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Oct 7 06:54:01 CEST 2005



On Thu, 6 Oct 2005, Mike Cheponis wrote:

> I'm trying to update an Entry's textvariable several times within my
> Button handler, like so:
>
> from Tkinter import *
> from time import *
>
> def my_update():
>    for i in range(3):
>      tv.set("Now it's %d"%i)
>      sleep(1)
>
> root=Tk()
> tv=StringVar()
> Entry(textvariable=tv).pack()
> tv.set("Initial Value of StringVar")
> Button(text="Update", command=my_update).pack()
> root.mainloop()


Hi Mike,

The problem is that the GUI needs control back to be able to update the
GUI display.  At the moment, there's only one thread of execution, and the
call to time.sleep() deprives the GUI of the control it needs to draw
things.

Tkinter has a particular way of doing sleep()-like behavior that interacts
better with the GUI.  We can use the "after()" method to tell the GUI to
do some action after some period of time.

Here's a quick-and-dirty example:

######
import Tkinter
root = Tkinter.Tk()
label = Tkinter.Label(root, text="hello")
label.pack()

def doCountUpdate(n):
    label['text'] = n
    label.after(1000, doCountUpdate, n + 1)

doCountUpdate(0)
root.mainloop()
######


The initial call to doCountUpdate() updates the label text, and then tells
the label: "after 1000 milliseconds (one second), call doCountUpdate
again, and with n+1 as its argument."  After we schedule this next update,
we give control back to the GUI, and trust that the GUI will keep its
promise to call our function after the timeout period.

For reference information on this, see:

http://www.pythonware.com/library/tkinter/introduction/x9507-alarm-handlers-and-other.htm

This isn't the only way to handle this sort of problem: another possible
approach involves the use of threads.  But you may want to try using
'after()' first, since I think it has an easier learning curve than
threads.


Best of wishes to you!



More information about the Tutor mailing list