Указатель в функции signal_connect не работает правильно - PullRequest
1 голос
/ 15 июня 2019

Я хочу использовать функцию g_signal_connect() для изменения данных в конкретном struct/class.Так что, на мой взгляд, лучше всего использовать указатель на struct.проблема в том, что информация указателя, кажется, постоянно меняется.

Я потратил много времени, чтобы выяснить, почему это происходит, но я понятия не имею.Я могу скомпилировать и запустить код без каких-либо ошибок, но вывод всегда отличается.

Позже я хочу использовать несколько event_box для подключения к массиву структуры или массиву класса (event_box[0] connect to data[0], ...).

Я надеюсь, что кто-то понимает, что я имею в виду, и я был бы рад любой помощи.

#include<gtk/gtk.h>

struct d
{
bool status;
int ID;
};

void end_program(GtkWidget *wid, gpointer ptr)
{
gtk_main_quit();
}

void box_click(GtkWidget *wid, gpointer user_data)
{
    struct d *data = (struct d*)user_data;
    printf("status  = %i\n", data->status);
    printf("ID      = %i\n", data->ID);
}

int main (int argc, char *argv[])
{
    struct d data;
    data.status = 0;
    data.ID = 1;

    gtk_init(&argc, &argv);

    GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    GtkWidget *event_box  = gtk_event_box_new();
    g_signal_connect(G_OBJECT(event_box), "button_press_event", G_CALLBACK(box_click), &data); 

    gtk_container_add(GTK_CONTAINER(win), event_box);
    gtk_widget_show_all(win);
    g_signal_connect(win, "delete_event", G_CALLBACK(end_program),NULL);

    gtk_main();

    return 0;
}

Вывод, если я нажимаю на поле несколько раз:

status  = 4
ID      = 32193184
status  = 5
ID      = 32193184
status  = 4
ID      = 32193184
status  = 6
ID      = 32193184
status  = 4
ID      = 32193184

1 Ответ

1 голос
/ 16 июня 2019

Я надеюсь, что кто-то понимает, о чем я, и я был бы рад любому помощь.

Ну, да .. Вы используете неправильный прототип функции для button-press-event. Прототип для button-press-event:

The “button-press-event” signal

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

( примечание: сигнал правильно "button-press-event" вместо "button_press_event", хотя есть #define, позволяющий работать второй форме)

См. GtkWidget (Руководство по Gtk + 3) . Итак, как должна выглядеть ваша функция:

gboolean box_click(GtkWidget *wid, GdkEvent *event, gpointer user_data)
{
    struct d *data = user_data;            /* no need for cast, gpointer is void* */
    g_print("status  = %d\n", data->status);
    g_print("ID      = %d\n", data->ID);

    return TRUE;    /* to prevent further handling, FALSE otherwise */

    (void)wid;      /* cast to void to avoid unused var warning */
    (void)event;
}

Дополнительные гниды

Используйте g_print вместо printf, используйте gboolean вместо bool. В то время как прохождение address of подходит для небольших структур, для больших структур следует выделить g_slice_new.

...