I want to use the g_signal_connect()
function to change data in a specific struct/class
. So, in my opinion, the best way is to use a pointer to the struct
. the problem is that the information of the pointer seems to be changing all the time.
I spent a lot of time to figure out why is that happening, but I have no idea. I can compile and run the code without any error but the output is always different.
Later I want to use several event_box to connect to an array of struct or an array of a class (event_box[0]
connect to data[0]
,...).
I hope someone understands what I mean and I would be happy about any help.
#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;
}
Output if I click the box several times:
status = 4
ID = 32193184
status = 5
ID = 32193184
status = 4
ID = 32193184
status = 6
ID = 32193184
status = 4
ID = 32193184
I hope someone understands what I mean and I would be happy about any help.
Well, yes.. You are using the wrong function prototype for a button-press-event
. The prototype for a button-press-event
is:
The “button-press-event” signal
gboolean
user_function (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
(note: the signal is properly "button-press-event"
instead of "button_press_event"
, though there is a #define
allowing the second form to work)
See GtkWidget (Gtk+3 Manual). So what your function should look like is:
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;
}
Additional Nits
Use g_print
instead of printf
, use gboolean
instead of bool
. While passing the address of
is fine for small structs, for large structs you should allocate with g_slice_new
.