LinuxForum.Fans
Тема

C/GTK+ и Cairo, рисование на Gtk Drawing Area

Автор: mr_mag 3 сообщений 2085 просмотров
#187402

Доброго всем дня!

Есть маленькая программка с одним окошком, на котором есть тулбар с двумя кнопками, Drawing Area и статусбар. Нужно, чтобы при нажатии на кнопку тулбара "Refresh", на Drawing Area при помощи Cairo рисовалась простейшая геометрическая фигура (в данном случае, квадрат) и фон заливался другим цветом. Реализовал рисование через expose_event, все компилируется без ошибок, но нифига не рисует. Долго пытался понять, в чем дело и в итоге обнаружил, что expose_event не посылается виджету Drawing Area ни во время первого старта приложения, ни принудительно при нажатии на кнопку "Refresh" (посредством gdk_window_process_all_updates). Т.е. даже если написать в expose_event gtk_main_quit(), ничего не происходит.

Если кто разбирается в Cairo и может помочь, буду безмерно благодарен! Код приведен ниже, если чего, прошу не пинать ногами и не посылать учить матчасть, программирую под линуксом неделю.

Код компилется вот так: gcc pe.c -o pe `pkg-config --cflags --libs gtk+-3.0`

Собственно, сабж:

text

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

static void destroy (GtkWidget *window, gpointer data) { gtk_main_quit (); }

static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_parent_window(widget));

cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 2); cairo_rectangle (cr, 50, 50, 50, 50); cairo_stroke_preserve (cr); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill (cr);

cairo_destroy (cr);

return FALSE; }

static void force_expose_event (GtkWidget *widget, gpointer data) { gdk_window_process_all_updates (); }

int main (int argc, char *argv[]) { gtk_init (&argc, &argv);

GtkWidget *window, *table, *toolbar, *drawing_area, *statusbar; GtkToolItem *btn_refresh, *btn_quit;

window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Cairo Test"); gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);

table = gtk_table_new (8, 8, FALSE); gtk_container_add (GTK_CONTAINER (window), table);

toolbar = gtk_toolbar_new (); gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);

btn_refresh = gtk_tool_button_new_from_stock (GTK_STOCK_REFRESH); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), btn_refresh, 0); g_signal_connect (G_OBJECT (btn_refresh), "clicked", G_CALLBACK (force_expose_event), NULL);

btn_quit = gtk_tool_button_new_from_stock (GTK_STOCK_QUIT); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), btn_quit, 1); g_signal_connect (G_OBJECT (btn_quit), "clicked", G_CALLBACK (gtk_main_quit), NULL);

gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (toolbar), 0, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);

drawing_area = gtk_drawing_area_new (); gtk_widget_set_size_request (GTK_WIDGET (drawing_area), 800, 480); GdkColor white; gdk_color_parse ("white", &white); gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white); gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (drawing_area), 0, 3, 2, 3, GTK_FILL, GTK_FILL, 10, 10); g_signal_connect (G_OBJECT (drawing_area), "expose_event", G_CALLBACK (on_expose_event), NULL);

statusbar = gtk_statusbar_new (); gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (statusbar), 0, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0);

gtk_widget_show_all (window);

gtk_main ();

return 0; }

ps

По поводу матчасти - если у кого есть хорошие мануалы по Cairo и(или) рисованию при помощи средств GTK+, дайте пожалуйста ссылочку!

#187412

Спасибо, там пример подобный тому, что мне нужно, но реализация иная. Буду разбираться. Если найдется время посмотреть мой код, глянь пожалуйста, ок?

Войдите или зарегистрируйтесь, чтобы ответить.