The new rally signal uses a callback that already passes the Cairo context as a parameter, you do not need to do things like window = widget.get_window()
, as you did in PyGtk, to get the cairo context while the exposure signal is present. In PYGObject, it's easier:
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
That is, if you do not need PixBuf, but if you need it for something else, you have several options:
- To have both objects in memory. If both are downloaded from PNG, there should not be many problems besides memory loss.
- Convert GdkPixbuf to PIL Image, then PIL Image to a data array, and then create a Cairo ImageSurface from this data array using create_for_data (). Yak: S I don't know better, sorry: S
- Use the Gdk.cairo_set_source_pixbuf () suggested by hock. This is apparently the right way to draw Pixbuf in ImageSurface, but it's completely fearless (and so I hate this Introspection stuff, everything looks like C, like a bad C port).
If you choose the terrible second option, here's how:
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)
Note: create_for_data () is not yet available for Python3 , only for Python2 .
Check also my answer on how to use a double buffer in PyGObject, if that is what you are trying to achieve: Drawing in PyGobject (python3)
respectfully