[pygtk] delete lines from draw area
danny.milo at gmx.net
Sat Nov 20 00:15:36 WST 2004
Am Mittwoch, den 17.11.2004, 23:30 -0400 schrieb Luis Useche:
> i wanna know, how can delete a line from a draw area that i do with a gc.
'delete' a line ? What do you mean ?
[ memorized objects ]
This is not a vector graphics canvas so 'line' isnt a memorized object
and *not* stored in the drawingarea. So in the worst case you'd have to
restore each pixel from before (when you did save them before calling
As far as I understand it is like this:
[ Drawable ]
A Drawable is an object with a signal where one will be told 'hey, I
need to be redrawed' ('expose-event') and then one has to redraw
everything onto it again (and again... and again... and again...)
[ Drawingarea ]
A Drawingarea is a gtk widget that contains a drawable (within the
[ 'expose-event' signal ]
So you'd have to register a function with 'expose-event' signal (with
connect()) and, elsewhere, from the time on where you want the line to
vanish, modify some program data that removes the line from its memory.
[ queue_draw() ]
Then request it to redraw with queue_draw().
Sometime later X/Gdk/Gtk will ask you to redraw by emitting the expose
signal you told it to emit.
Your callback will be called.
[ in the callback ]
You clear the drawingarea (with draw_rectangle or something)
You check your program data and iterate over all objects [since now you
memorize the line objects because they are stored in your object], and
call draw_*() for each of them.
[ flickering, double buffering ]
This could flicker like hell. So use a Pixmap as temporary storage(a
Pixmap can be used the same as a drawable) and only at the end copy the
Pixmap content into the original drawingarea. Given a half-recent
graphics adapter it will stop flickering (since ideally the Pixmap ->
Drawable transfer is done entirely in graphics adapter memory which are
[ other kinds of classes ]
To be complete, other kinds are:
A Pixmap is a in-(graphics-adapter-)memory but offscreen Drawable that
will remember what is drawn on it (just the pixels, so it has hazy
A Bitmap is a Pixmap with only black/white (on/off) pixels.
A Pixbuf is a storage class that will store some picture and allow only
primitive manipulation (no draw_line, no draw_spline, no
draw_mandelbrot, just some alpha blending and mixing and matching :)).
To show a pixbuf it is drawn on a drawable (usually a Pixmap or some
Drawable like GdkWindow).
Therefore there is a 'Image', that is a widget somewhat like a
Drawingarea that draws either a pixbuf or pixmap automatically (that is,
when and 'expose-event' arrives, the callback from the Image will call
draw_pixbuf to redraw it again... and again... and again... when told
> self.area.window.draw_line(self.gc, x1, y1, x2, y2)
[ bad ways ]
If you meant to draw over the existing line using the background color
(which usually doesnt do it right), then you probably could do it like
this [although you should not, for reasons listed below]
color = self.black_color
self.area.window.draw_line(self.gc, x1frombefore, y1frombefore,
[ why bad ]
Reasons not to:
- it will wreck havoc on the other still visible lines in the
drawingarea (try intersecting lines and you'll see)
- one doesnt know if the widget background is a picture rather than a
color (I think that holds less true for Drawingareas though)
[ 'good' ways ]
So there were some ways introduced in ancient times: :)
[ XOR ]
The fastest is XOR drawing the line. That will draw the line pixel for
pixel, but not by *setting* each drawable pixel to the 'foreground
color' (from the gc), but by using XOR with each existing drawable pixel
and the 'foreground color' (from the gc).
because A XOR B XOR B = A, it will vanish with every second draw_line
- fast like hell
- need to find a clearly visible "B" (that will give a color that is
distinguishable from A easily)
- before changing anything on the underlying lines, one always has to
remove the 'xored once' line first (by xor-drawing it), then draw the
underlying lines normally, then readd the 'xored' line (by xor-drawing
it) again. Can get tedious.
[ redraw all ]
Thus nowadays usually one just redraws all the stuff and be over with.
(since comps are faster)
As I said, in your callback you'll just leave the line out that you dont
want to see anymore and it is gone :)
[ damage system ]
Some use a 'damage system' that will notice changes in areas and add the
areas to a list of damaged areas. When redrawing it will only redraw
what has been 'damaged' (well, one only stores rectangular areas so most
of the time more than needed is redrawn).
(I think gtk can do that too, since there is a queue_draw_area call. I
am too lazy and so never checked the arguments passed to the
'expose-event' callbacks, guess they contain one such rectangle area :))
Err... yeah... got somewhat sidetracked.
More info on what you want to do please :)
www.keyserver.net key id A334AEA6
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : nicht verfügbar
Dateityp : application/pgp-signature
Dateigröße : 189 bytes
Beschreibung: Dies ist ein digital signierter Nachrichtenteil
URL : http://www.daa.com.au/pipermail/pygtk/attachments/20041119/66ed7b60/attachment.bin
More information about the pygtk