【问题标题】:How do I pass multiple variables as data with gtk signals如何使用 gtk 信号将多个变量作为数据传递
【发布时间】:2012-08-04 12:50:52
【问题描述】:

我有一个小程序,其中 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);

【问题讨论】:

    标签: c gtk


    【解决方案1】:

    当然你可以使用空指针数组,但是如果你想传递不同类型的值(尤其是类型长于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);
    

    【讨论】:

    • 但是指针的大小不总是一样的吗?我不能只将指针传递给数组中的变量并在回调函数中取消引用它们吗?
    • @JV 在实践中,指针大小相同,所以sizeof(void *) == sizeof(char *) == sizeof(whatever *),但C不保证这一点。
    • @JV 被称为面向对象的编程设计 :)(也可能是哈希表)
    • @JV 我刚刚向你解释过了。自动变量在创建它们的函数返回时被释放。
    • 不,不是。你会怎么做?
    【解决方案2】:

    您可以使用 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");
    

    【讨论】:

    • 在销毁对象之前不要忘记释放数据。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-29
      • 2023-03-24
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      相关资源
      最近更新 更多