инициализация GtkImage в c - PullRequest
0 голосов
/ 15 апреля 2020

Я сталкиваюсь с ошибкой сегментации, когда пытаюсь заставить Gtkwidget указывать на адрес памяти, где я загружаю png из файла. Я хочу, чтобы card[6].image отображал изображение, которое я загрузил в card[0].image, и я хотел бы удалить то же изображение из card[0].image.

struct my_image {

    const char *path;
    GtkWidget *image;
};

void create_window() {

    GtkWidget *window;
    GtkWidget *headbar;
    GtkWidget *vbox;
    GtkWidget *hbox_3;
    GtkWidget *hbox_table;
    GtkWidget *hbox_1;
    GtkWidget *hbox_2;
    GtkWidget *about_button;
    GtkWidget *event_box1, *event_box2, *event_box3;

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    headbar = gtk_header_bar_new();
    about_button = gtk_button_new_with_mnemonic("CLick");
    event_box1 = gtk_event_box_new ();
    event_box2 = gtk_event_box_new ();
    event_box3 = gtk_event_box_new ();
    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 50);   
    hbox_3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
    hbox_table = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
    hbox_2= gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
    hbox_1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);   

    gtk_header_bar_set_title (GTK_HEADER_BAR (headbar), "Myprogram");
    gtk_window_set_title (GTK_WINDOW (window), "Myprogram");    
    gtk_window_set_titlebar (GTK_WINDOW (window), headbar);
    gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headbar), TRUE);
    gtk_window_maximize (GTK_WINDOW (window));  

    card[0].path = pile[0];
    card[1].path = pile[1];
    card[2].path = pile[2];

    card[0].image = gtk_image_new_from_file (card[0].path);
    card[1].image = gtk_image_new_from_file (card[1].path);
    card[2].image = gtk_image_new_from_file (card[2].path);

    card[3].path = "c/fort.png";
    card[4].path = "c/fort.png";
    card[5].path = "c/fort.png";

    card[3].image = gtk_image_new_from_file (card[3].path);
    card[4].image = gtk_image_new_from_file (card[4].path);
    card[5].image = gtk_image_new_from_file (card[5].path);


    card[6].image = gtk_image_new ();
    card[7].image = gtk_image_new ();

    printf("card 0 address = %u\n", card[0].image);
    printf("card 6 address = %u\n", card[6].image);     

    card[8].path = pile[39];
    card[9].path = "c/mazzo.png";
    card[8].image = gtk_image_new_from_file (card[8].path);
    card[9].image = gtk_image_new_from_file (card[9].path);

    g_signal_connect (about_button, "clicked", G_CALLfort (activate_about), NULL);
    g_signal_connect (G_OBJECT (event_box1), "button_press_event", G_CALLfort (card1_clicked), card);
    g_signal_connect (G_OBJECT (event_box2), "button_press_event", G_CALLfort (card2_clicked), card);
    g_signal_connect (G_OBJECT (event_box3), "button_press_event", G_CALLfort (card3_clicked), card);
    g_signal_connect (G_OBJECT (window), "destroy", G_CALLfort (destroy), NULL);

    gtk_container_add(GTK_CONTAINER (headbar), about_button);
    gtk_container_add(GTK_CONTAINER (window), vbox);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_3);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_table);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_2);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_1);
    gtk_container_add(GTK_CONTAINER (hbox_2), card[8].image);
    gtk_container_add(GTK_CONTAINER (hbox_2), card[9].image);
    gtk_container_add(GTK_CONTAINER (hbox_1), event_box1);
    gtk_container_add(GTK_CONTAINER (hbox_1), event_box2);
    gtk_container_add(GTK_CONTAINER (hbox_1), event_box3);
    gtk_container_add(GTK_CONTAINER (event_box1), card[0].image);
    gtk_container_add(GTK_CONTAINER (event_box2), card[1].image);
    gtk_container_add(GTK_CONTAINER (event_box3), card[2].image);
    gtk_container_add(GTK_CONTAINER (hbox_3), card[3].image);
    gtk_container_add(GTK_CONTAINER (hbox_3), card[4].image);
    gtk_container_add(GTK_CONTAINER (hbox_3), card[5].image);
    gtk_container_add(GTK_CONTAINER (hbox_table), card[6].image);
    gtk_container_add(GTK_CONTAINER (hbox_table), card[7].image);   

    gtk_widget_show_all (window);

    gtk_main();

}

void card1_clicked (GtkWidget *window, struct my_image *card)
{
    printf("%s\n", card[0].path);
    card[6].image = card[0].image;
    /*gtk_image_set_from_file(GTK_IMAGE(card[6].image), card[0].path);*/
}

, изображения изначально отображаются корректно, но когда триггер card1_clciked эта строка card[6].image = card[0].image; выдает ошибку сегментации. Я не уверен, правильно ли я загружаю изображение и как загрузить другое изображение, используя тот же виджет; Я также пытался использовать функцию /*gtk_image_set_from_file(GTK_IMAGE(card[6].image), card[0].path);* с тем же эффектом.

1 Ответ

1 голос
/ 15 апреля 2020

Ваша функция обратного вызова для сигнала button_press_event не определена правильно.

Инструкция сообщает нам, как она должна выглядеть:

// The “button-press-event” signal

gboolean
user_function (GtkWidget *widget,
               GdkEvent  *event,
               gpointer   user_data)

В вашей функции вам не хватает одного параметра:

void card1_clicked (GtkWidget *window, struct my_image *card)

Это означает, что вы используете указатель event для чтения массива card, что вызывает некоторый недопустимый доступ для чтения.

Кроме того, вы этого не делаете укажите требуемое логическое возвращаемое значение.

...