F**** YEAH I DREW ANOTHER RECTANGLE! Icons in PyGTK continued…
Welcome to Part II of learning to draw custom icons in PyGTK with PyCairo. In the previous post we learned how to draw on a gtk.DrawingArea the hard way. Now let’s simplify things; after all, who has time to wait for “expose-event”s before drawing?? In a recession???
Another suggested method for drawing in a Cairo/Drawable context with PyGTK is to draw to a gtk.gdk.Pixmap, then throw that schizzle on a gtk.Image. This mitigates all that window craziness and in fact I’m not sure why I didn’t do it this way the first time. Probably because I had no clue what I was doing.
Here’s the code for our adorable rectangle; explanations follow. See my previous post for the Window class–it’s just a simplified gtk.Window which adds a child in its constructor. Yes, because I am lazy.
1 2 3 4 5 6 7 8 9 10 | draw = gtk.Image() pixmap = gtk.gdk.Pixmap(None, 100, 100, 24) cr = pixmap.cairo_create() cr.set_source_rgb(1, 0, 0) cr.rectangle(10, 10, 20, 20) cr.fill() draw.set_from_pixmap(pixmap, None) window = Window(child=draw, width=300, height=300) gtk.main() |
And voila, we get a red square with a whacked-out looking background. So what are we doing here? First we create the Image, and then we create a Pixmap with no drawable/window because it is being drawn offscreen. This pixmap has a 100 pixel width and 100 pixel height and a color depth of 24 bits. Specifying the depth is mandatory since our Drawable (the first value) is None. A depth of 1 indicates a monochromatic image.
From the pixmap we can create our cairo context, and get to drawing! The crazy-ass cairo Context documentation should tell you everything you need to know about PyCairo drawing methods, and make your head explode as well–fringe benefit!
After we finish drawing and fill in our circle with some happy red paint, we use the set_from_pixmap method of the Image class with a mask of None, and then add our image to the window and it’s game over! Too easy, right? Not really, but that’s PyGTK.
To get rid of the crazy background, set the source color to the desired background color and call paint on the cairo context. To get the background color of the widget you’re drawing into, use widget.get_style().bg, which returns a list of gtk.gdk.Color objects which are used to draw the background. I grabbed the first one and got lucky: it matched!
Code looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import gtk from screwdriver.window import Window import cairo draw = gtk.Image() pixmap = gtk.gdk.Pixmap(None, 100, 100, 24) cr = pixmap.cairo_create() bg_color = draw.get_style().bg[0] cr.set_source_color(bg_color) cr.paint() cr.set_source_rgb(1, 0, 0) cr.rectangle(10, 10, 20, 20) cr.fill() draw.set_from_pixmap(pixmap, None) window = Window(child=draw, width=300, height=300) gtk.main() |
There you have it! An easier way to draw icons. PART III will be the icon class and final product. Stay tuned.