Problem with tkinter mainloop

Eric Brunel eric_brunel at despammed.com
Tue Nov 30 06:11:38 EST 2004


k2riddim wrote:
> Hello,
> I'm a beginner with Python and Tkinter development.
> My application parse links in an html file. And I use Tkinter to
> implement a GUI. This GUI has a button to launch the parse treatment,
> and a status bar to show the state of the treatment.
> I know that because of the mainloop, my tkinter application freeze
> while my treatment isn't finished. That's why my status bar doesn't
> update herself in real time.
> I wanted to use the after or the after_idle function, but I don't
> really understand why it doesn't work.

after and after_idle won't help you: the action you register in these methods 
are called only when the main loop gets back the control, and your problem is 
precisely that the main loop does not get it...

The method you're probably looking for is update_idletasks: it updates the 
display without getting any user event. There's another method called update, 
but this one does process user events, so it may call some of your code if such 
an event is pending. This is usually not what you want to do, except in some 
very rare cases.

Here is how it may look like in your code, along with a few remarks on your code:

> 
> My apps is build approximately like that :
> 
> ---Gui.py---
> class Gui(Frame):

Why do you inherit from Frame? A Tkinter Frame is a generic container widget; 
this is not a window. IMHO, you'd better inherit from Tk for your main window or 
from Toplevel for other windows. You'd also get better control on the actual 
window, since some of the methods available on Tk and Toplevel are not available 
on other widgets (e.g. geometry or protocol)

>         def __init__(self):
>                 ...
>         def launchTreatment(self):
>                b = Treatment()
>                self.after(b.treatment.parse)

This cannot be your code; the after methods takes two parameters: the number of 
milliseconds to wait before the action will be called and the action itself. You 
only provide the action here. But again, the after method won't help you to get 
what you want...

> 
> ---Treatment.py---
> class Treatment():
>         def __init__(self):
>                 ...
>         def parse(self):
>                ...
>                GUIinstance.status.set("state 1")

This is where the GUIinstance.update_idletasks() should go.

>                ...
>                GUIinstance.status.set("state 2")

Another GUIinstance.update_idletasks() here.

> 
> 
> ---Main.py---
> #instanciation of classes
> GUIinstance = Gui

Again, this cannot be your code, since you do not instantiate the class here. 
The correct line should be:

GUIinstance = Gui()

It is usually far better to post a working example demonstrating the problem you 
have instead of just extracting a few lines of your whole code. This will help 
people who are willing to help to understand exactly what is going on.

HTH
-- 
- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com



More information about the Python-list mailing list