如何使用gtk信号将多个变量作为数据传递

我有一个小程序,其中gtk信号回调函数需要2或3个变量。

我不想制作这些全局变量(项目的整个目标是整洁而且)我不想制作一个完整的结构,所以我可以将一个小部件和一个编译的正则表达式发送给一个函数。

据我所见, g_signal_connect只允许单个数据变量。

这样做最有效的方法可能是一个指向这两个对象的void指针数组吗? 像这样的东西?

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

当然,您可以使用void指针数组,但是如果要传递具有不同类型的值(尤其是类型长度大于sizeof(void *) ),则不能使用数组。 对于这些,您几乎肯定希望将它们包装在结构中并将结构的地址作为数据参数传递。

例:

 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); 

当然,不要忘记在回调函数中free(data) (假设它是单独使用的)。

编辑:你想要一个带有void **的例子,你在这里(这很丑陋,我不建议你使用它 – 或者因为为原始类型分配一个单元素数组会浪费你的拍摄或因为施法指向void *的非指针是不好的做法……):

 void **data = malloc(sizeof(data[0]) * n_elements); type1 *element1_ptr = malloc(sizeof(first_item)); *element1_ptr = first_item; data[0] = element1_ptr; /* etc. */ 

解放他们:

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

您可以使用g_object_set_data()和g_object_get_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)); 

在回调中,您可以获得如下数据:

 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"); 

扩展H2CO3的答案,您还可以设置数据(我强烈建议使用结构,顺便说一句)在信号处理程序断开时自动释放:

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