В этом простом примере внутри функции do_draw
cairo знает, на какой поверхности рисовать, поскольку она использует аргумент cairo_t * cr
. Я не понимаю, откуда берется cr
, я полагаю, что он был автоматически создан GTK при создании виджета drawarea
.
Я хочу рисовать (более сложные) вещи на том же cr
вне функции do_draw
, но я не знаю, как получить доступ к 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.
Нет, это оболочка вокруг графического контекста, предоставляемого событием отрисовки оконной системы. Независимо от того, создается ли он заново при каждом розыгрыше, зависит от оконной системы, но вы не можете получить этот дескриптор без существование в событии рисования.
Например, в Windows WM_PAINT
получает контекст рисования с BeginPaint
в своем обработчике. Но если вы хотите создать свой собственный контекст в другом месте, используйте GetDC
, чтобы получить его.
Однако Gtk поддерживает только событие рисования для рисования на виджетах (т.е. первая половина вышеперечисленного). Таким образом, вы не можете получить контекст рисования вне события рисования, вам нужно вызвать событие рисования и позволить ему рисовать себя.
Да, вы можете рисовать только внутри вашего обработчика отрисовки.
нашел аналогичный вопрос здесь: так 43633012.
значит ли это, что моим единственным решением было бы вызвать мою функцию так:
do_draw_more(cairo_t * cr)
изнутриdo_draw
?