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