From: Steve C. <ste...@ya...> - 2005-03-17 02:47:16
|
On Wed, 2005-03-16 at 09:00 -0600, John Hunter wrote: > I looked at this briefly and am a little confused by something. The > base class FigureCanvasGTK.expose_event has this in the doc string > > """Expose_event for all GTK backends > Should not be overridden. > > but then the derived class > > class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg): > > does in fact override it. A while ago I started updating the GTK backends to be more consistent (by using the same draw(), expose_event() etc methods) and also so they create just one Renderer instance and reuse it for all drawing. I completed doing this for GTK and GTKCairo. With GTKAgg, it looked a bit more complicated, and seeing that GTKAgg was already working quite well I decided to leave it and come back to it later. So my intention was to have all GTK backends using a standard draw() and expose_event() from the base class and just have a specific _renderer_init() to set their own renderer. To make this work by reusing one Renderer instance I needed to add new methods to each Renderer: def _set_pixmap(self, pixmap): def _set_width_height(self, width, height): which are called by _render_figure(). I still think this approach is a good idea, but it may need to be modified to allow it to work with GTKAgg. The patch I committed to CVS does the first part (using standard draw() and expose()), but not the second part - GTKAgg still uses multiple Renderer instances. The patch also fixes another little problem that GTKAgg has. If you display a figure, then obscure the window and expose the window (without resizing it), GTKAgg will completely redraw the window, which may give a flicker in the obscured/exposed area for a complicated figure, whereas GTK and GTKCairo will redraw the original figure from the double- buffered memory, which is much faster and flicker-free. > I inserted a debug print statement into > FigureCanvasGTKAgg.expose_event and it is not called until the loop is > over. I think this is because the call to sleep is preventing the > idle handler from ever getting engaged. I think Joachim just used the sleep call just to make the problem obvious, and that the problem is there even if sleep is not called, except that it may flash so quickly you can not be sure what you saw. > Perhaps Joachim would be better off using a gtk timer to handle his > animation. Basically, matplotlib tries to provide a GUI neutral way > to do animation (eg anim.py) but if you want to do something > semi-sophisticated like alter the timing between draws, you should use > the GUI specific functionality for this, eg gtk timers. > > Here is an example > [...] Thats works OK, but requires that users write their own animation draw() routines, whereas using double-buffering for GTKAgg makes it available to all GTKAgg users for free. I think double-buffering is generally what you want to use for flicker-free drawing, and there does not seem to be any performance penalty from the few tests I made. Steve |