John Hunter wrote:

I have a problem that has cropped up in a couple of different
circumstances.
1) I have a GtkDialog above my GtkWindow and I want to drag it off to
the side of the main window to use some controls in the dialog.
The draq across the window triggers a large number of expose events
in rapid succession. I would like to delay the redrawing until
after the last one because redrawing is expensive for my window

2) I have a navigation tool to scroll plot axes in a GtkDrawingArea
with the wheel mouse. If the user makes a large, fast scroll, I
only want to redraw at the end of the scroll, rather than for each
step of the wheel mouse turn.

I can imagine how to code this, by trapping events of a certain type
and only handling an event if no successive event comes into the trap
for a fixed time lag. But I suspect this is a common problem and am
wondering if there is a gtk builtin way or other standard way of
handling this situation.

There are two answers to this question.

First the simple one: use GTK 2.0 and pygtk-1.99.x. With GTK 2.0, the expose events will be merged for you, so that if multiple expose events are generated while you are doing your drawing, you will only get a single expose event afterwards. You also get double buffering for free by doing this.

The more difficult one applies if you can't upgrade for some reason. You will need to split your expose event handler into two bits. You need to split your drawing code out into a separate function that will be used as an idle handler. When you receive an expose event, simply record the area that needs to be drawn somewhere and queue your idle handler, saving the idle handler id (the return value of gtk.idle_add) somewhere (global variable, instance variable, etc).

If your expose handler gets triggered and the idle handler has already been queued (you will know this because you saved the handler ID), simply update the area to redraw and return.

In your idle handler, the first thing you should do is to take a copy of the area to redraw and set the saved handler ID to zero (to signal that the handler has been called). Then do all your drawing and return FALSE to indicate that the idle handler should not be requeued.

This can be simplified further if your drawing function always redraws the entire window. In that case, you don't need to worry about saving or updating the redraw area.

James.

--
Email: [EMAIL PROTECTED] | Linux.conf.au http://linux.conf.au/
WWW: http://www.daa.com.au/~james/ | Jan 22-25 Perth, Western Australia.


_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Reply via email to