How to update status bar in wxPython?

Steven Sartorius ssartor at bellatlantic.net
Thu Mar 29 07:19:53 EST 2001


In article <OEtw6.238$nyH.5111956 at news.randori.com>, "Robin Dunn"
<robin at stop.spam.alldunn.com> wrote:

> "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!


Thanks for the response.  I kind to thought I might have to restructure
my code.  Good thing I'm not doing anything this weekend....


Steve



More information about the Python-list mailing list