6

I'm currently learning GTK+ via PyGobject and need something like a canvas. I already searched the docs and found two widgets that seem likely to do the job: GtkDrawingArea and GtkLayout. I need a few basic functions like fillrect or drawline ... In fact these functions are available from c but I couldn't find directions how to use them from python. Can you recommend a tutorial or manpage that deals with their python equivalents ?

If you have a better idea how to get something similar to a canvas every tip would be appreciated. I'm still learning and as long as it can be embedded within my Gtk application I'd be content with any solution.

lhk
  • 27,458
  • 30
  • 122
  • 201
  • 1
    The apropriate widget for that is GtkDrawingArea. I don't have any sample right now, but you should use pycairo to draw into it, as a reaction to the `expose` event. – rodrigo Dec 22 '11 at 19:19
  • That means GtkDrawingArea is only a container that can be filled by other frameworks ? Is there any canvas included in GTK+ ? – lhk Dec 22 '11 at 19:33
  • 1
    @rodrigo The `expose-event` signal has been replaced by the `draw` signal in gtk3 according to the [reference manual](http://developer.gnome.org/gtk3/3.3/ch25s02.html#id1413935). – jcollado Dec 22 '11 at 20:00
  • I read up on pycairo and the possibility to "fill" a drawingarea. It seems like it's possible to let pygame do the job. However common belief is that integrating pygame into gtk+ means trouble: The event systems / update mechanisms crash. I have to admit: As I've already used pygame I'd like to use it again, so I'm a little biased. – lhk Dec 22 '11 at 20:01
  • What makes pycairo stand out? @rodrigo why did you recommend it ? – lhk Dec 22 '11 at 20:01
  • @lhk - Cairo is pretty much the standard free (as in freedom) 2D graphic library, at least on *nix systems. PyCairo just wraps it. Embedding PyGame in GTK is a -1 for me. :) – mac Dec 22 '11 at 20:18
  • @lhk The modern and recommended way to draw in GTK+ is using cairo (the only way in Gtk+3, actually). So if you use PyGTK then using PyCairo is just expected. – rodrigo Dec 22 '11 at 22:03

1 Answers1

13

In order to illustrate my points made in the comments, let me post a quick'n'dirty PyGtk example that uses a GtkDrawingArea to create a canvas and paints into it using cairo

CORRECTION: you said PyGObject, that is Gtk+3, so the example is as follows (the main difference is that there is no expose event, instead it is draw and a cairo context is already passed as a parameter):

#!/usr/bin/python
from gi.repository import Gtk
import cairo
import math

def OnDraw(w, cr):
    cr.set_source_rgb(1, 1, 0)
    cr.arc(320,240,100, 0, 2*math.pi)
    cr.fill_preserve()

    cr.set_source_rgb(0, 0, 0)
    cr.stroke()

    cr.arc(280,210,20, 0, 2*math.pi)
    cr.arc(360,210,20, 0, 2*math.pi)
    cr.fill()

    cr.set_line_width(10)
    cr.set_line_cap(cairo.LINE_CAP_ROUND)
    cr.arc(320, 240, 60, math.pi/4, math.pi*3/4)
    cr.stroke()

w = Gtk.Window()
w.set_default_size(640, 480)
a = Gtk.DrawingArea()
w.add(a)

w.connect('destroy', Gtk.main_quit)
a.connect('draw', OnDraw)

w.show_all()

Gtk.main()
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Ok, the advantages over integrating pygame are more than obvious. The fact that a cairo context is provided with the event is just beautiful. I'll mark this as an answer for the question. Of course I'd appreciate alternative ideas although this seems perfect. – lhk Dec 23 '11 at 10:23