我有一个小应用程序使用DrawingArea
使用PyGObject
和GTK3
绘制简单地图。
我使用
加载Pixbuf
from gi.repository import Gtk, GdkPixbuf
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size("logo.png", 25, 25)
然后尝试在DrawingArea
的绘制事件信号中绘制它
def draw(self, widget, context):
window = widget.get_window()
ctx = window.cairo_create()
ctx.set_source_pixbuf(pixbuf, 0, 0)
但我收到错误消息
"AttributeError: 'cairo.Context' object has no attribute 'set_source_pixbuf'"
如果我正确地阅读Gtk2 to Gtk3 migration guide,这应该可行。 我做错了什么?
答案 0 :(得分:10)
新的 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,但如果你需要它来做其他事情你有几个选择:
如果你选择了糟糕的第二个选项,那么:
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()为not yet available for Python3,only for Python2。
如果这是你想要实现的目标,请查看我在PyGObject中如何使用双缓冲区的答案:Drawing in PyGobject (python3)
亲切的问候
答案 1 :(得分:7)
以下似乎可以完成这项工作:
def draw(self, widget, context):
Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0)
context.paint()
仍然存在一个问题:这是首选方式吗?