On Wed, Feb 06, 2008 at 01:21:30AM +0100, Gael Varoquaux wrote:
> On Tue, Feb 05, 2008 at 07:16:59PM -0500, Paul Kienzle wrote:
> > How about giving flush_events() an until=condition and timeout=n keywords 
> > so that flush_events becomes:
> 
> >         if timeout > 0: set timer event which triggers out_of_time
> >     while get next event:
> >            process event
> >            if out_of_time or until(): break
> 
> I'd say this is exactly the way to do it. The problem is that under GTK
> is seems fairly easy to do, under Tk it seems feasible, but under Qt and
> under Wx I have no clue how to do this. We can always fallback to
> busy-waiting for these toolkits.

There are two ways to do this in wx.  

One is to use eventloop.Dispatch() which waits until the next available
event:

    def _onTimeout(self,evt):
        'event loop timer completed'
        self._event_loop_running = False
        
    def event_loop(self, done=lambda:False, timeout=0):
        'run the event loop until done or timeout'
        
        timer = wx.Timer(self)
        self._event_loop_running = True
        if timeout > 0:
            timer.Start(timeout*1000, oneShot=True)
            self.Bind(wx.EVT_TIMER, self._onTimeout, timer)
        loop = wx.EventLoop()
        while self._event_loop_running and loop.Dispatch() and not done():
            #print "Processing event"
            pass

        self._event_loop_running = False
        timer.Stop()

The other is to trigger a loop.Exit() from the click callback.  


Rather than passing a stop condition to the event_loop method, the 
user would call start_event_loop to start collecting events,
and stop_event_loop in the event callback when the terminating 
condition is reached.  In the ginput example, this is just calling
self.fig.canvas.stop_event_loop() rather than self.done = True in the
callback.  The code for this is:

    def __init__
        ...
        self._event_loop = wx.EventLoop()
        ...

    def start_event_loop(self, timeout=0):
        timer = wx.Timer(self)
        if timeout > 0:
            timer.Start(timeout*1000, oneShot=True)
            self.Bind(wx.EVT_TIMER, self.stop_event_loop, timer)
        self._event_loop.Run()
        timer.Stop()

    def stop_event_loop(self, event=None):
        if self._event_loop.IsRunning(): 
            self._event_loop.Exit()

Note that we need to also check for the window closing while the
event loop is running, which we can do using the following at the
beginning of start_event_loop:

        root = self.GetTopLevelParent()
        root.Bind(wx.EVT_CLOSE, self.stop_event_loop)

This will unfortunately kill any window kill event that the
application defined.

We may also want to give the application direct access to the timer 
for the purpose of creating animations independent of the toolkit.

        - Paul

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to