在 GTK window 中访问 Cairo 上下文 'cr'

Access to Cairo context 'cr' in GTK window

在这个简单的示例中,函数 do_draw 中的 cairo 知道要在哪个表面上绘制,因为它使用了参数 cairo_t * cr 。我不明白 cr 的来源,我想它是 GTK 在创建小部件 drawarea.
时自动创建的 我想从 do_draw 函数外部在同一个 cr 上绘制(更复杂的)东西,但我不知道如何从另一个函数访问 cr

#include <cairo.h>
#include <gtk/gtk.h>

// gcc move.c -o move $(pkg-config --cflags --libs cairo --libs gtk+-3.0)

gboolean timer = TRUE;
int i = 1;


static gboolean do_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
    cairo_select_font_face(cr, "Courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size(cr, 60);
    cairo_move_to(cr, i, 300);
    cairo_show_text(cr, "moving");
    return FALSE;
}

static gboolean time_handler(GtkWidget *widget)
{
    if (i > 15) return FALSE;
    printf("drawing frame %d\n", i);
    gtk_widget_queue_draw(widget);
    i++;
    return TRUE;
}


int main(int argc, char *argv[])
{
    // gtk inits
    gtk_init(&argc, &argv);
    GtkWidget *window  = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *drawarea = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), drawarea);
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
    g_signal_connect(G_OBJECT(drawarea), "draw", G_CALLBACK(do_draw), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    // timer
    g_timeout_add(200, (GSourceFunc) time_handler, (gpointer) window);
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

`

As far as i understand, it looks as if 'cr' was automatically created by GTK with the creation of the widget drawarea.

不,它是窗口系统绘制事件提供的图形上下文的包装器。无论是否 re-created 每次绘制都是窗口化的 system-dependent,但如果没有 在绘制事件中 ,您将无法获得该句柄。

例如,在 Windows 下,WM_PAINT 在其处理程序中获取带有 BeginPaint 的绘图上下文。但是如果你想在别处创建你自己的上下文,你可以使用 GetDC 来代替。

不过Gtk只支持paint事件在widgets上绘制(即上面的前半部分)。所以你不能在paint事件之外获取绘图上下文,你需要触发paint事件让它自己绘制。