How do I pass multiple variables as data with gtk signals

大憨熊 提交于 2019-12-21 04:01:01

问题


I have a small program where a gtk signal callback function needs 2 or 3 variables.

I don't want to make these global variables (The entire goal of the project is to be neat and tidy) and I don't want to make a whole struct just so I can send a widget and a compiled regex to a function.

As far as I've seen g_signal_connect only allows for a single data variable.

Would the most efficient way of doing this perhaps be an array of void pointers to the two objects in question? Something like this?

void * data[2];
data[0] = widget;
data[1] = compiledregex;
g_signal_connect(save,"clicked",G_CALLBACK(callbackfunction),data);

回答1:


Of course you can use arrays of void pointers, but if you want to pass around values with different types (especially values whose type is longer than sizeof(void *)), you can't use arrays. For these, you'll almost certainly want to wrap them in a struct and pass the struct's address as the data parameter.

Example:

struct my_struct *data = malloc(sizeof(*data));
data->field_one = value_one;
data->field_two = value_two; /* etc. */

g_signal_connect(save, "clicked", callback, data);

Of course, don't forget to free(data) in the callback function (assuming it's for single use).

Edit: as you wanted an example with void **, here you are (this is ugly, and I don't recommend you to use this -- either because allocating a one-element array for primitive types is wasting your shoot or because casting a non-pointer to void * is bad practice...):

void **data = malloc(sizeof(data[0]) * n_elements);

type1 *element1_ptr = malloc(sizeof(first_item));
*element1_ptr = first_item;
data[0] = element1_ptr;

/* etc. */

To free them:

int i;
for (i = 0; i < n_elements; i++)
    free(data[i]);

free(data);



回答2:


You can use g_object_set_data() and g_object_get_data(). First, set the data:

g_object_set_data(G_OBJECT(my_edit), "my_label", my_label);
g_object_set_data(G_OBJECT(my_edit), "age", GINT_TO_POINTER(age));

and in the callback you can get the data like so:

gint age = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "age"));
GtkWidget *my_label = g_object_get_data(G_OBJECT(widget), "my_label");



回答3:


Expanding on H2CO3's answer, you can also set the data (and I strongly recommend using a struct, by the way) to be freed automatically when the signal handler is disconnected:

g_signal_connect_data(save, "clicked", callback, data, (GClosureNotify)free, 0);


来源:https://stackoverflow.com/questions/11808819/how-do-i-pass-multiple-variables-as-data-with-gtk-signals

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!