[cairo] drawing shapes from events

Gerdus van Zyl gerdusvanzyl at gmail.com
Tue Jul 15 12:26:49 PDT 2008


In GTK you can only draw in the expose event. Two ways of doing what
you want: first, only draw on expose, as in store mouse coordinates
and use that to draw on expose. second method is using your own
surface using create_similiar or ImageSurface and draw to it on mouse
event. Then on expose you paint that surface to the expose surface.

~Gerdus

On Tue, Jul 15, 2008 at 9:13 PM, Mr SZ <sk8in_zombi at yahoo.com.au> wrote:
> Hi,
>
> I'm trying to create a rectangle when the user presses or releases the mouse
> over a cairo object.I'm using the eventBox to capture the mouse events.
> Now the problem is the shapes is beng drawn when I call it from the
> expose_event event handler and nothing happens when I call the same from the
> mouse release event handler.
>
> Here is my code :
>
> #!/usr/bin/env python
>
> import sys
> import cairo
> import gtk
>
>
> start = None #Starting co-ords
> stop = None #Ending co-ords
> box = None  #Tuple of co-ords for drawing rect
> ctx = None #Cairo Widget
> def button_press(widget, event, surface):
>     global start
>     start = (int(event.x),int(event.y))
> def motion_notify(widget, event, surface):
>     pass
> def button_release(widget, event, surface):
>     global stop,ctx
>     ctx = None
>     ctx = widget.window.cairo_create()
>     ctx.set_source_surface(surface, 0,0)
>     ctx.paint()
>     print ctx
>     stop =  (int(event.x),int(event.y))
>     box = (start[0],start[1])
>     draw_dotrect(ctx,box)
>     print "Released" + str(box)
>
> def draw_dotrect(ctx,box):
>     ctx.set_source_rgba(0, 0, 0,0.5)
>     ctx.save()
>     ctx.new_path()
>     ctx.translate(3*20, 0)
>     square(ctx,box)
>     ctx.fill()
>     ctx.restore()
>     ctx.set_line_width(20 / 16)
>     ctx.set_tolerance(0.1)
>     ctx.set_line_join(cairo.LINE_JOIN_MITER)
>     ctx.set_dash([20/2.0, 20/2.0], 8)
>     ctx.save()
>     ctx.new_path()
>     ctx.set_source_rgb(0,0 ,0 )
>     ctx.translate(3*20, 0)
>     square(ctx,box)
>     ctx.stroke_preserve()
>     ctx.restore()
>
> def expose_event(widget, event, surface):
>     global ctx
>     ctx = widget.window.cairo_create()
>     ctx.set_source_surface(surface, 0,0)
>     ctx.paint()
>
>     #draw_dotrect(ctx,(20,20)) # If called from here,it works
>
>
> def square(ctx,box):
>     ctx.move_to(0, 0)
>     ctx.rel_line_to(2*50, 0)
>     ctx.rel_line_to(0, 2*50)
>     ctx.rel_line_to(-2*50, 0)
>     ctx.close_path()
>
>     if len(sys.argv) != 2:
>         raise SystemExit('usage: png_view.py png_file')
>
> filename = sys.argv[1]
>
> surface = cairo.ImageSurface.create_from_png(filename)
> Width  = surface.get_width()
> Height = surface.get_height()
>
> win = gtk.Window()
> win.connect('destroy', gtk.main_quit)
>
> event_box = gtk.EventBox()
> win.add(event_box)
>
> drawingarea = gtk.DrawingArea()
> event_box.add(drawingarea)
>
> drawingarea.connect('expose_event', expose_event, surface)
> event_box.connect('button_press_event',button_press,surface)
> event_box.connect('button_release_event',button_release,surface)
> event_box.connect('motion_notify_event',motion_notify,surface)
>
> drawingarea.set_size_request(Width,Height)
>
> win.show_all()
> gtk.main()
>
> It doesn't throw me any error.I hardcoded the box to simplify things .    I
> also create a new ctx in the release event handler else it throws an
> error:CAIRO_STATUS_SURFACE_FINISHED
>
> Any ideas why ?
>
> " life isn't heavy enough,it flies away and floats far above action"
> ________________________________
> Start at the new Yahoo!7 for a better online experience - Start Here.
> _______________________________________________
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo
>


More information about the cairo mailing list