How to draw any GTK widget on top of Cairo surface
Asked Answered
P

2

13

I would like to save the looks of a GTK window, and all the buttons and other widgets it contains to a PNG or PDF file. Cairo supports drawing on such surfaces. Could I somehow ask a GTK widget to draw itself on Cairo surface? A code sample would be much appreciated, since I am a newcomer to both GTK and Cairo. Python is my language of choice.

Peruse answered 9/2, 2011 at 11:47 Comment(0)
D
10

In C, you can put your buttons and widgets in a GtkOffscreenWindow using gtk_widget_reparent() and then use gtk_offscreen_window_get_pixbuf() to render it onto a GdkPixbuf, which you can then save to a file. Sorry I don't have any Python code, but I don't think the offscreen window is available in PyGTK yet.

Dichotomy answered 9/2, 2011 at 14:40 Comment(0)
U
10

What ptomato says. Use a Gtk.OffscreenWindow if you need to do it off screen, otherwise just get the Gdk window and the widget's allocation to clip it. Here is a snippet that can be used to get a snapshot of any widget. As the following code shows, you can also use the Gtk.Widget.draw() method to render it in the Cairo context.

from gi.repository import Gtk
import cairo

WINDOW_WIDTH, WINDOW_HEIGHT = 400, 300

window = Gtk.OffscreenWindow()
window.set_default_size(WINDOW_WIDTH, WINDOW_HEIGHT)
window.show()

canvas = Gtk.HBox()
window.add(canvas)
canvas.show()

button = Gtk.Button("Hello World!")
canvas.add(button)
button.show()

# this is needed, otherwise the screenshot is black:
while Gtk.events_pending():
    Gtk.main_iteration()

surf = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                          WINDOW_WIDTH, WINDOW_HEIGHT)

cr = cairo.Context(surf)
canvas.draw(cr)
surf.write_to_png('test.png')

You can temporarily reparent a widget (as ptomato said) to this Gtk.OffscreenWindow, in order to make the snapshot.

original_parent = canvas.get_parent()
canvas.reparent(offscreen_window)

# do snapshot

canvas.reparent(original_parent)
Urgency answered 6/3, 2012 at 4:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.