How to update status bar in wxPython?

Robin Dunn robin at stop.spam.alldunn.com
Wed Mar 28 17:33:17 EST 2001


"Steven Sartorius" <ssartor at bellatlantic.net> wrote in message
news:5Tpw6.2172$K%.667185 at typhoon1.ba-dsg.net...
> I'm a newbie to GUI programming in general so apologies if this is a
FAQ....
>
> I've got a Python script that does some heavy duty number crunching and
file
> I/O.  To track the progress of the script I print a series of messages to
the
> console/x-term ("Working on file #....", etc,etc).  As a project, I
decided to
> guify the script with wxPython and Boa-constructor.  I've successfully
built a
> window with a single button, a couple of text input fields and a status
bar;
> clicking the button fires off the script.  What I'm trying to do (so far
> unsuccessfully) is redirect the progress messages from the console to the
> status bar on the window.  Because I'm retrofitting an existing script,
I've
> just replaced the original 'print' statements with
> 'statusBar.SetStatusText("Working on file....") and (for good measure)
> 'statusBar.Refresh()'.  This approach kind of works....the status bar
shows
> the final progress message ("All data processed")  but only after I force
the
> window to redraw (moving it or covering and then uncovering it).  I'm sure
I'm
> missing something basic here so any help would be much appreciated.
>

When you click the button and "fire off the script" you are effectivly
blocking the GUI until the script is complete.  You need to allow the GUI's
main loop to run in order for new events to be dispatched and other
housework types of things to happen.  When you call statusBar.Refresh() you
are simply requesting that a paint event be sent ot the statusBar, but as
you've seen if the event is never dispatched to the window then it is never
actually refreshed.

One way to allow the main loop to run from within the middle of some long
running task is to call wxYield, which will return when there are no more
events waiting to be proccessed.  Unfortunatly there are potential
reentrancy issues you need to deal with when using wxYield, for example what
if the user clicks on your launcher button while a script is already
running, and then the code calls wxYield?

A better way is to refactor your long running task so that it can be
executed a chunk (or iteration) at a time from an EVT_IDLE event handler.
Each time the handler is called do the next chunk of the task and if there
is more to be done call event.RequestMore() before returning.  This lets the
code return to the main loop frequently so the GUI continues receiving
events and can be updated, but all extra time is spent running your task.

If the task is not easily broken into chunks then you can run it in a
background thread, but then there are a few things you need to do specially
to allow your thread to communicate back to the GUI thread.  See the demo
and also the wxpython-users archives for details.

--
Robin Dunn
Software Craftsman
robin at AllDunn.com       Java give you jitters?
http://wxPython.org      Relax with wxPython!






More information about the Python-list mailing list