Как нарисовать любой виджет GTK поверх поверхности Каира

Я хотел бы сохранить внешний вид окна GTK, а также все кнопки и другие виджеты, которые он содержит в PNG или PDF файле. Каир поддерживает нанесение таких поверхностей. Могу ли я каким-то образом спросить виджет GTK, чтобы нарисовать себя на поверхности Каира? Образец кода был бы очень оценен, так как я новичок как в GTK, так и в Каире. Python - мой язык выбора.

Ответ 1

В C вы можете поместить свои кнопки и виджеты в GtkOffscreenWindow с помощью gtk_widget_reparent(), а затем используйте gtk_offscreen_window_get_pixbuf() для рендеринга на GdkPixbuf, который затем можно сохранить в файл. Извините, у меня нет кода Python, но я не думаю, что внеэкранное окно доступно еще в PyGTK.

Ответ 2

Что говорит ptomato. Используйте Gtk.OffscreenWindow, если вам нужно сделать это за пределами экрана, иначе просто получите окно Gdk и распределение виджета, чтобы скопировать его. Вот фрагмент, который можно использовать для получения моментального снимка любого виджета. Как показано в следующем коде, вы также можете использовать метод Gtk.Widget.draw() для рендеринга его в контексте Каира.

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

Вы можете временно просмотреть виджет (как сказал ptomato) этому Gtk.OffscreenWindow, чтобы сделать снимок.

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

# do snapshot

canvas.reparent(original_parent)