Tkinter performance

Fredrik Lundh fredrik at pythonware.com
Tue Apr 20 09:48:50 EDT 1999


Randall Hopper <aa8vb at vislab.epa.gov> wrote:
> Note that the canvas seems to have respectable optimizations in place so
> the less that is visible (e.g. the more you're zoomed in, the faster
> redraws get.  Also if only a partial area needs redrawn, it redraws it
> fairly quickly relative to the full-expose frame rate.  It's obvious
> there's some optimization going on when you load to make drawing faster.

some background: the canvas widget uses a straight-forward
"damage/repair" model.  changes to the canvas, and external
events such as Expose, all update a single "dirty rectangle".
they also register an idle task (after_idle) which redraws the
canvas when you get back to the main loop.

when it's time to redraw the canvas, the widget starts by
allocating a pixmap (on X windows, this is an image memory
stored on the display) with the same size as the dirty rectangle.
it then loops over the canvas items, and redraws *all* items
whose bounding box touch the dirty rectangle (this means
that diagonal lines may be redrawn also if they don't actually
cover the rectangle, but this is usually no big deal).  finally,
the widget copies the pixmap to the display (this last step is
a very fast operation on all modern hardware), and releases
the pixmap.

a few additional notes:

-- most Tk widgets use double-buffering to prevent flicker
(this includes simple widgets like buttons and labels).  there's
no way to change this in current version of Tk.

-- most Tk widgets also use delayed drawing.  that is, they
respond to modifications and external events by scheduling
an idle task, not by updating the screen directly.  there's
no way to change this in current versions of Tk.

-- the repeated allocation of pixmaps can seriously affect
performance if you're animating stuff in a maximized window
on a large truecolor display... (we all have 1800x1440 24-bit
displays, don't we?)

-- since the canvas uses a *single* dirty rectangle, you can
get better performance in some situations by forcing updates.
for example, if you're changing things in different parts of the
canvas without returning to the main loop, adding explicit
calls to update_idletasks() allows the canvas to update a
few small rectangles, instead of a large one with many more
objects.

-- the text widget is a bit smarter than the canvas...

-- guess I should mention uiToolkit here, but I'll leave that
for another day...

</F>





More information about the Python-list mailing list