Hello Chris,

I was finally able to solve this problem to my satisfaction, so I want to share 
my solution here in case it serves anyone in the future.


The basic problem is that mouse movement events often arrive at a rate much 
higher than what a given app is actually able to process in time. Nothing 
breaks, but all other GUI elements freeze up while you're dragging some object 
around the canvas.


The workaround I previously had (only let through one event each x millisec) 
only worked halfway: When stopping the mouse movement, the last couple of 
events were usually swallowed, making the canvas lag behind by a few pixels, 
which looked really bad and made it impossible to fine tune the position of an 
object.


Of all events arriving (usually large batches in close succession), recent ones 
obsolete the earlier ones, so only a few events in between (and specially the 
last one) need to be processed. However, the workaround was unable to 
distinguish which that last one was, and chose events to let through basically 
at random.


A better way to throttle update frequency is to change the OnMove event handler 
to just store the coordinates (or whatever data you need from the event) in a 
special variable, which takes practically no time. Then, bind a different 
handler to EVT_IDLE, and trigger canvas redraws from there. Since multiple Move 
events keep overwriting the same variable over and over, the OnIdle handler is 
guaranteed to see only the most recent one whenever it triggers:

    @Bind(wx.EVT_IDLE)
    def OnIdle(self,e):
        if self._coords is not None:
            coords = self._coords
            self._coords = None
            self.Update(coords)

This made the canvas both responsive and accurate, without even needing to 
improve performance of my redrawing methods. Since there are only a couple of 
dozen objects on the canvas at most, it makes sense for me to just remove all 
objects and recreate the view based on my underlying data, keeping the code 
able to process arbitrary changes to the canvas objects in a simple and elegant 
way.


 
Vitor




----- Mensaje original ----
> De: Christopher Barker <[email protected]>
> Para: Mailing List for the wxPython Float Canvas. <[email protected]>
> Enviado: miércoles, 25 de marzo, 2009 19:25:55
> Asunto: Re: [fc] FloatCanvas update issues
> 
> Vitor Bosshard wrote:
> > It's attached. I managed to keep it at ~100 lines.
> 
> I've take a look. It seems to work fine for me on OS-X, anyway.
> 
> A few comments, though:
> 
>     def UpdateCircles(self, coord):
>         self.RemoveObjects(self.circles)
>         self.circles = []
>         for i in range(25):
>             self.circles.append(self.AddCircle((coord[0]+i%5*5,coord[1]+i),
>                                          Diameter=10,
>                                          LineColor="White"))
> 
> 
> DrawObjects have a Move() method, so that you can move them without removing 
> them and re-creating them. There is also a SetPoint method, if you want to 
> set 
> their center points to a specific value:
> 
> for i, circle in enumerate(self.Circles):
>     circle.SetPoint((coord[0]+i%5*5,coord[1]+i))
> 
> 
> You also might want to put all the Circles in a Group object, but then you 
> have 
> to use Move(), rather than SetPoint.
> 
> I've enclosed an edited version.
> 
> -Chris
> 
> 
> 
> 
> 
> 
> 
> -- Christopher Barker, Ph.D.
> Oceanographer
> 
> Emergency Response Division
> NOAA/NOS/OR&R            (206) 526-6959   voice
> 7600 Sand Point Way NE   (206) 526-6329   fax
> Seattle, WA  98115       (206) 526-6317   main reception
> 
> [email protected]



      ¡Obtén la mejor experiencia en la web!&lt; Descarga gratis el nuevo 
Internet Explorer 8. http://downloads.yahoo.com/ieak8/?l=e1
_______________________________________________
FloatCanvas mailing list
[email protected]
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to