Пиксельная прозрачность в PyGTK

1

Как создать пиксельные карты PyGTK с одним значением пикселя, установленным на прозрачный? Я знаю, что это как-то связано с созданием pixmap глубины 1 и установки его как маски, но все, что я нахожу, это то, что он либо ничего не делает, либо полностью стирает мою pixmap при рисовании. На данный момент я создаю pixmap с

r = self.get_allocation()
p1 = gtk.gdk.Pixmap(self.window,r.width,r.height)
p1_c = p1.cairo_create()

затем нарисуйте черные линии по всему Каиру. То, что я хотел бы сделать, - это иметь всю область, не покрытую прозрачными линиями (делая белый прозрачный цвет, скажем), так что, когда я рисую его в окне с помощью draw_drawable, он оставляет все "под", нетронутыми.

Часто задаваемые вопросы и рассылки по этой проблеме наиболее бесполезны, поскольку они настолько устарели. Кто-то должен знать здесь!

Теги:
transparency
pygtk

2 ответа

1
Лучший ответ

Похоже, вы хотите использовать Pixbuf, а не Pixmap. Pixbuf включает альфа-настройку, которая даст вам прозрачность, тогда как Pixmap не делает.

  • 1
    Благодарю. Я просмотрел документацию PyGTK Pixbuf, но, кажется, нет никакого способа использовать их в качестве поверхности для рисования в Каире. Нужно ли конвертировать туда и обратно между Pixbuf и ImageSurface, чтобы использовать их?
2

Я не думаю, что вы можете делать то, что хотите, с помощью 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()

Если это то, что вы ищете, я бы рекомендовал обновить заголовок вопроса, чтобы отразить вашу настоящую потребность:).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню