Tkinter: update_idletasks

klappnase klappnase at web.de
Sat May 22 17:03:54 EDT 2004


Jeffrey Barish <jeffbarish at starband.net> wrote in message news:<mailman.159.1085178672.6949.python-list at python.org>...

> Ah.  I had a hunch that might be the case.  However, that is not the
> behavior that I am seeing.  First, in response to your questions: (1) I
> am on Linux (there are other platforms?); (2) I am using Python 2.3;
> (3) it is difficult to extract a piece of the code, but I will attempt
> to describe more clearly what I am doing.  There is a button with a
> handler.  In the handler I use popen3 to launch a program that takes a
> long time to execute.  I monitor its progress in a while loop by
> reading a status line that it produces on stderr.  The status line
> provides information about percentage complete; I use that information
> to update the MessageBar in my GUI.  When the status line indicates
> that the process is done, I exit the while loop and return from the
> button handler.  I tried running update_idletasks on the MessageBar in
> the while loop.  I tried running it on the root window, even though the
> information you provided indicated that it doesn't matter what class
> owns the method -- and my experience certainly does not contradict that
> statement.  In every case, only the MessageBar updates.  Well, that's
> not entirely true.  I also move a tag in a text widget; the previously
> and newly tagged text redraws.  The only technique I have found that
> permits the main window to update is to run most of the handler in a
> separate thread.  The problem I am having with that approach is that
> the MessageBar then flashes in an annoying way (the background seems to
> go to white at every update and then gets redrawn to gray -- which
> happens only when the while loop is in its own thread).  Any other
> thoughts would be much appreciated.

I've been using a Tkinter filehandler for similar tasks and didn't
have the problems you describe.
Here's a pseudo-code snippet to illustrate what I did:

from Tkinter import *
import os, fcntl, popen2

def button_callback(self, event):
    #the function that's bound to the button
    #dialog window with progress bar:
    self.pw = ProgressWindow.ProgressWindow()
    selectedfiles = ' '.join(tracklist)
    normalizecmd = 'exec normalize -m ' + selectedfiles
    self.pp = popen2.Popen4(normalizecmd)
    self.mkfilehandler(self.pp, self.getprogress)

def mkfilehandler(self, popen4object, function):
    #creates the filehandler
    fileobject = popen4object.fromchild
    filedescr = fileobject.fileno()
    fcntl.fcntl(filedescr, fcntl.F_SETFL, os.O_NONBLOCK)
    tkinter.createfilehandler(fileobject, READABLE, function)

def getprogress(self, fileobject, event_type):
    message = self.pp.fromchild.read()
    if message == '':
        # process has finished
        # this could be checked with "if self.pp.poll() != -1:" either
        tkinter.deletefilehandler(self.pp.fromchild)
        <...clean up stuff here...>
        self.pp = None
    else:
        <...parse the output messages, extract progress values,
etc....>
        # update the progress bar (update_idletasks() is called from
it's set() method):
        self.pw.set(value=progress)

I hope this helps

Michael



More information about the Python-list mailing list