4

I am writing a small application using PyGI which will interactively draw a line on a Gtk.DrawingArea between mouse clicks. But I am unable to figure out how to draw using the cairo context at the coordinates returned by the mouse click event.

How should the drawing be handled from 'button-press-event' to draw a pattern similar to that produced by the 'draw' callback in the attached code?

class MyApp(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Draw on button press")
        self.set_size_request(800, 500)
        self.connect('delete-event', Gtk.main_quit)

        self.drawing_area = Gtk.DrawingArea()
        self.drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) 
        self.drawing_area.connect('draw', self.on_drawing_area_draw)
        self.drawing_area.connect('button-press-event', self.on_drawing_area_button_press)
        self.drawing_area.show()
        self.add(self.drawing_area)

        self.show_all()

    def on_drawing_area_button_press(self, widget, event):
        print "Mouse clicked... at ", event.x, ", ", event.y
        # How to draw a line starting at this point on the drawing area?        
        return True

    def on_drawing_area_draw(self, drawing_area, cairo_context):
        cairo_context.move_to(50, 50)
        cairo_context.rel_line_to(0, 200)
        cairo_context.rel_line_to(200, 0)
        cairo_context.rel_line_to(0, -200)
        cairo_context.set_source_rgb(0, 0, 0)
        cairo_context.stroke()

        return False

app = MyApp()
Gtk.main()
3

What you should do is set variables that are drawn in the draw callback. If you want it to redraw itself you can use this to force it to:

drawing_area.queue_draw()

Edit: Here is an example of code you may use:

clicks = [];

def on_drawing_area_button_press(self, widget, event):
    print "Mouse clicked... at ", event.x, ", ", event.y
    clicks.append([event.x, event.y])
    drawing_area.queue_draw()

    return True

def on_drawing_area_draw(self, drawing_area, cairo_context):
    cairo_context.move_to(50, 50)
    for point in clicks
        cairo_context.line_to(point[0], point[1])

    cairo_context.stroke()

    return False

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.