GTK3 cairo g_signal_connect:不明白这一点

GTK3 cairo g_signal_connect: Dont get the point

我正在尝试解决这个问题,当我点击 "button1" 时,"on_draw_event"-函数被调用(有效)并且在我的 "darea"-drawing_area(那是行不通的)。

这是我的代码:

    #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), "绘制", G_CALLBACK(on_draw_event), NULL);" 该线将被绘制,但我希望它等待我的按钮点击。希望有人能帮帮我,问题不大。

谢谢。

如前所述,您的示例崩溃是因为您将绘图回调连接到 clicked 信号。调用时,回调会收到无意义的参数并终止。

为了"wait for the button click",引入一个标志,告诉你按钮是否被点击。在 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;
}