wxPython before MainLoop

Chris Mellon arkanes at gmail.com
Fri Aug 10 21:46:26 CEST 2007

On 8/9/07, Heikki Toivonen <heikki at osafoundation.org> wrote:
> [david] wrote:
> > I'd like to refresh the display before I start the main loop.
> We have this kind of situation in Chandler, where we display and update
> the splash screen before we enter MainLoop.
> 1. Create app object
>    http://lxr.osafoundation.org/source/chandler/Chandler.py#080
> 2. During app object creation, in OnInit, put up splash screen and update it
> http://lxr.osafoundation.org/source/chandler/application/Application.py#433
> 3. The splash screen refresh is basically: draw new stuff,
> self.Layout(), self.Update(), wx.Yield()
> http://lxr.osafoundation.org/source/chandler/application/Application.py#1421
> 3. Start MainLoop
>    http://lxr.osafoundation.org/source/chandler/Chandler.py#086

wxYield spins the event loop in place. This can have some serious
consequences if you aren't very careful with your usage, like
recursively entering event handlers. I generally consider it an
experts only interface, and avoid it.

Thankfully, in Python 2.5 you can do some very nice things with
Pythons generators. Basically, replace your wxYielding code with a
python generator that just yields where you used to wxYield, and then
call your generator repeatedly with wx.CallAfter.

Here's an (unpolished) example of a progress dialog that is updated
via generator:

import wx

def startupTask():
    for ii in xrange(1001):
        cont, skip = yield ii, "step %s"%str(ii)
        if not cont:
            raise StopIteration

class GeneratorProgress(wx.ProgressDialog):
    """ Progress dialog fed via generator.
    Task let should be a python generator that yields (value, message) tuples
    and is sent (continue, skip) tuples, as per the arguments to and return
    values from the wx.ProgressDialog.Update method.
    def __init__(self, title, message, tasklet, *args, **kwargs):
        super(GeneratorProgress, self).__init__(title, message, *args, **kwargs)
        self.tasklet = tasklet

    def iterate(self, cont=None, skip=None):
            if cont is None and skip is None:
                value, msg = self.tasklet.next()
                value, msg = self.tasklet.send((cont, skip))
            cont, skip = self.Update(value, msg)
            wx.CallAfter(self.iterate, cont, skip)
        except StopIteration:

def main():
    app = wx.App(False)
    f = wx.Frame(None)
    pg = GeneratorProgress("Startup", "running task...",
startupTask(), parent=f, maximum=1000)

if __name__ == '__main__':

More information about the Python-list mailing list