2016-01-07 2 views
-1

Я пытаюсь исправить это, когда я нажимаю кнопку «button1», вызывается «on_draw_event» -функция (которая работает), и строка отображается в моей «darea» - drawing_area (это не работает).GTK3 cairo g_signal_connect: Dont get the point

Вот мой код:

#include <gtk/gtk.h> 

static gboolean on_draw_event(GtkWidget *button, cairo_t *darea) 
{ 
    printf ("function: on_draw_event\n"); 
    cairo_set_source_rgb(darea, 0, 255, 0); 
    cairo_set_line_width(darea, 0.5); 

    cairo_move_to(darea, 0, 100); 
    cairo_line_to(darea, 400, 100); 
    cairo_stroke(darea); 
    return FALSE; 
} 


int main (int argc, char *argv[]) 
{ 
    GtkWidget *window; 
    GtkWidget *darea; 
    GtkWidget *myGrid; 
    GtkWidget *button1; 
    GtkWidget *button2; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_POPUP); 
    myGrid = gtk_grid_new(); 
    darea = gtk_drawing_area_new(); 

    gtk_widget_set_size_request(darea, 400, 400); 
    button1 = gtk_button_new_with_label ("BUTTON 1"); 
    button2 = gtk_button_new_with_label ("QUIT"); 

    gtk_grid_attach(GTK_GRID(myGrid), button1, 0, 0, 1, 1); 
    gtk_grid_attach(GTK_GRID(myGrid), darea, 0, 1, 1, 1); 
    gtk_grid_attach(GTK_GRID(myGrid), button2, 0, 2, 1, 1); 
    gtk_container_add(GTK_CONTAINER(window), myGrid); 

    g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(gtk_main_quit), NULL); 
    g_signal_connect(button1, "clicked", G_CALLBACK(on_draw_event), darea); 

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 

Если я Канг "g_signal_connect (button1, "щелкнул", G_CALLBACK (on_draw_event), darea);" - «g_signal_connect (G_OBJECT (darea)», «draw», G_CALLBACK (on_draw_event), NULL); линия будет нарисована, но я хочу, чтобы она ждала нажатия на кнопку. Надеюсь, кто-то может остановить меня, не может быть большой проблемой.

спасибо.

ответ

1

Как отправлено, ваш пример вылетает из-за того, что вы подключаете обратный вызов чертежа к сигналу clicked. При вызове обратный вызов получает бессмысленные аргументы и умирает.

Чтобы «дождаться нажатия кнопки», введите флаг, указывающий, была ли нажата кнопка. Проконсультируйтесь с этим флагом в on_draw_event и установите его в обратном вызове clicked кнопки.

Ваш пример модифицирован для реализации выше, будет выглядеть следующим образом:

#include <gtk/gtk.h> 

static gboolean on_draw_event(GtkWidget *darea, cairo_t *cr, 
           gboolean *draw_line) 
{ 
    if (!*draw_line) 
     return FALSE; 
    printf ("function: on_draw_event\n"); 
    cairo_set_source_rgb(cr, 0, 255, 0); 
    cairo_set_line_width(cr, 0.5); 

    cairo_move_to(cr, 0, 100); 
    cairo_line_to(cr, 400, 100); 
    cairo_stroke(cr); 
    return FALSE; 
} 

static void on_button1_clicked(GtkWidget *button, gboolean *draw_line) 
{ 
    *draw_line = TRUE; 
    /* Make sure the widget is repainted after the click. 
     gtk_widget_queue_draw() should better be invoked with just the 
     drawing area, but this code accesses the common parent for 
     simplicity. Passing darea in a struct whose address is provided as 
     user_data (along with gboolean *draw_line) is left as exercise. */ 
    gtk_widget_queue_draw(gtk_widget_get_parent(button)); 
} 


int main (int argc, char *argv[]) 
{ 
    GtkWidget *window; 
    GtkWidget *darea; 
    GtkWidget *myGrid; 
    GtkWidget *button1; 
    GtkWidget *button2; 
    gboolean draw_line = FALSE; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_POPUP); 
    myGrid = gtk_grid_new(); 
    darea = gtk_drawing_area_new(); 

    gtk_widget_set_size_request(darea, 400, 400); 
    button1 = gtk_button_new_with_label ("BUTTON 1"); 
    button2 = gtk_button_new_with_label ("QUIT"); 

    gtk_grid_attach(GTK_GRID(myGrid), button1, 0, 0, 1, 1); 
    gtk_grid_attach(GTK_GRID(myGrid), darea, 0, 1, 1, 1); 
    gtk_grid_attach(GTK_GRID(myGrid), button2, 0, 2, 1, 1); 
    gtk_container_add(GTK_CONTAINER(window), myGrid); 

    g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(gtk_main_quit), NULL); 
    g_signal_connect(button1, "clicked", G_CALLBACK(on_button1_clicked), &draw_line); 
    g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), &draw_line); 

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 
+0

большое спасибо, работает отлично, и теперь я знаю, как справиться с этим. я хотел бы показать вам мой новый код, но я не знаю, как это сделать. просто напишите этот комментарий. просто небольшая ошибка, просто «возврат» не работает. я изменил на «return FALSE». – Arcanix

+0

@Arcanix Чтобы показать код, вы можете загрузить его на [сайт pastebin] (http://pastebin.com) и опубликовать короткий комментарий в комментарии. Я исправил ответ, чтобы вернуть «FALSE», спасибо за исправление. – user4815162342

+0

спасибо за этот намек. вы можете найти мой новый код здесь: http://pastebin.com/c9F5pw0s Я знаю, что это не лучший код, но он работает. Я еще не работал с struct, но я буду использовать его больше в моих следующих проектах. – Arcanix

Смежные вопросы