新的
draw信号使用一个回调函数,该函数已将cairo上下文作为参数传递,您不需要像在PyGtk中那样执行
window = widget.get_window()
等操作来获取cairo上下文,同时处理
expose-event信号。在PYGObject中更加简单。
import cairo
class Foo(object):
def __init__(self):
(...)
self.image = cairo.ImageSurface.create_from_png('logo.png')
(...)
def draw(self, widget, context):
if self.image is not None:
context.set_source_surface(self.image, 0.0, 0.0)
context.paint()
else:
print('Invalid image')
return False
如果您不需要PixBuf,但如果您需要它来做其他事情,您有几个选择:
- 将两个对象都保存在内存中。如果两者都是从PNG加载的,则除了浪费内存之外,不应该有太多问题。
- 将GdkPixbuf转换为PIL Image,然后将PIL Image转换为数据数组,然后使用create_for_data()从该数据数组创建Cairo ImageSurface。Yak:S我不知道更好的方法,抱歉:S
- 使用Gdk.cairo_set_source_pixbuf(),由hock提出。这似乎是在ImageSurface中绘制Pixbuf的正确方法,但它完全不符合Pythonic(这就是为什么我讨厌这个Introspection东西的原因,所有东西看起来像C一样,就像一个糟糕的C移植)。
如果您选择可怕的第二个选项,以下是如何操作:
import Image
import array
from gi.repository import Gtk, GdkPixbuf
width = 25
height = 25
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('logo.png', width, height)
pil_image = Image.fromstring('RGBA', (width, height), pixbuf.get_pixels())
byte_array = array.array('B', pil_image.tostring())
cairo_surface = cairo.ImageSurface.create_for_data(byte_array, cairo.FORMAT_ARGB32, width, height, width * 4)
请注意,
create_for_data()目前
仅适用于Python2,
对于Python3尚不可用。
如果您正在尝试实现双缓冲,请查看我在PyGObject中如何使用双缓冲的回答:
Drawing in PyGobject (python3)。
此致敬礼。
<gtk.gdk.X11Window object at 0xb71aab44 (GdkX11Window at 0x9db5aa0)>
对象,因此绘图区部件已实现。我似乎不知道在Gtk3中如何绘制pixbufs。 - gnirx