Я не думаю, что вы можете делать то, что вы хотите, с Pixmap
или Pixbuf
, но вот две стратегии реализации каракулей поверх существующего Widget
. Самый очевидный из них - это просто отловить событие рисования и нарисовать прямо на Widget
Drawable
без сохраненного изображения в середине:
from gtk import Window, Button, main
from math import pi
import cairo
w = Window()
b = Button("Draw on\ntop of me!")
def scribble_on(cr):
cr.set_source_rgb(0, 0, 0)
cr.rectangle(10, 10, 30, 30)
cr.fill()
cr.arc(50, 50, 10, 0, pi)
cr.stroke()
def expose_handler(widget, event):
cr = widget.window.cairo_create()
cr.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
cr.clip()
scribble_on(cr)
return False
b.connect_after("expose_event", expose_handler)
w.add(b)
w.set_size_request(100, 100)
w.show_all()
main()
Второй вариант, если вы хотите иметь промежуточное ARGB-изображение, которое не нужно обновлять каждый раз, когда запрашивается перерисовка, - это предварительно отрендерить изображение до ImageSurface
. Вот замена для expose_handler
выше, которая рисует изображение только один раз:
import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
scribble_on(cairo.Context(surface))
def expose_image_handler(widget, event):
cr = widget.window.cairo_create()
cr.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
cr.clip()
cr.set_source_surface(surface)
cr.paint()
Если это именно то, что вам нужно, я бы порекомендовал обновить название вопроса, чтобы отразить ваши реальные потребности:).