PyGTK中的Pixmap透明度

1 投票
2 回答
1783 浏览
提问于 2025-04-15 12:08

我想知道怎么在PyGTK中创建一个像素图(pixmap),让其中一个像素的值变成透明。我知道这和创建一个深度为1的像素图有关,并把它设置为遮罩,但我找到的资料要么没效果,要么在绘制时完全把我的像素图抹掉。目前,我是这样创建一个像素图的:

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

然后用Cairo在上面画黑线。我希望能做到的是,让所有没有被线覆盖的区域变成透明(比如把白色设为透明颜色),这样当我用draw_drawable把它绘制到窗口时,下面的内容就不会被覆盖。

关于这个问题的常见问答和邮件列表的帖子都很过时,根本没什么帮助。这里一定有人知道答案!

2 个回答

2

我觉得你可能无法用 PixmapPixbuf 实现你想要的效果,不过这里有两种方法可以在现有的 Widget 上进行涂鸦。最简单的方法就是捕捉绘制事件,然后直接在 WidgetDrawable 上绘制,不需要中间保存图像:

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()

如果这正是你想要的,我建议你更新一下问题的标题,让它更符合你的真实需求 :).

1

看起来你想使用的是Pixbuf,而不是Pixmap。Pixbuf可以设置透明度,这样就能实现透明效果,而Pixmap则没有这个功能。

撰写回答