如何在纯 C 中访问动态创建的 GTK Checkbutton

How to access dynamically created GTK Checkbutton in plain C

我创建了一个基于复选按钮输出 CSV 格式标签的程序。它们有很多,所以只有以编程方式创建它们才有意义。我在这个意义上是成功的,但我一直无法弄清楚如何获得他们的检查状态,因为你不能像普通的检查按钮一样访问它们。我解决了它,但现在进入我程序的 'polishing' 阶段,我真的很想能够通过取消选中它们来重置表单,但我不知道如何访问它们..首先,这是动态创建复选按钮的方式:

        for (int x = 0; x <= NUMBER_OF_STRING; x++)
        {
            if (tagArray[x] != NULL && strcmp(tagArray[x], "[=10=]"))
            {
                dynamic_checkBox = gtk_check_button_new_with_label(tagArray[x]);
                gtk_container_add(GTK_CONTAINER(flowBox), dynamic_checkBox);
                g_signal_connect(dynamic_checkBox, "toggled", G_CALLBACK(check_state), (gpointer)tagArray[x]);
            }
        }

所以效果很好..我能够使用一点 'hack' 创建一个额外的字符数组并将 'true' 或 'false' 字符串放在那里并使用 strcmp()基本上将我自己的 checked/unchecked 状态写入带有 gpointer 数据的数组,但与大多数 hack 一样,如果你做得不对,它会回来找你。现在我不知道该怎么做取消选中所有框并重置表格..

static void uncheck_button_clicked(GtkWidget* widget, gpointer data)
{
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dynamic_checkBox), FALSE);
}

如您所见,我正在调用全局 GtkWidget *dynamic_checkBox 但这对我没有帮助,因为它没有指向我需要的那个复选按钮的实际实例。那么如何我去访问这些复选框?我什至尝试用字符串动态声明新的 GtkWidgets 以便我可以访问它们,但这只会导致不兼容的类型错误......我一直在谷歌搜索和撞墙 2 天,现在没有结果。提前致谢。

首先,使用全局GtkWidget*GtkCheckButton*是没有意义的,因为无论如何你都有多个,所以每次你创建一个新的,它会覆盖旧值。

接下来,仍然有两种方法可以访问这些按钮:

  • 就像亚历山大在评论中建议的那样,您可以保留一个 GtkWidget*GtkCheckButton* 的列表(并在您创建按钮时添加它们)。这样,您可以遍历数组并取消选中它们。

  • 另一种选择是通过遍历其子项来使用所有复选按钮的父容器(但这实际上假设您在那里没有任何其他 GtkCheckButtons!)

GList *children = gtk_container_get_children (GTK_CONTAINER (flowbox));
for (GList *l = children; l; m = g_list_next (l)) {
    GtkWidget *child = l->data;

    // Note, you don't need this if-check if your flowbox only contains checkbuttons.
    // Bote 2: this *will* turn off also unrelated check buttons
    if (GTK_IS_CHECK_BUTTON (child)) {
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (child), FALSE);
    }
}

附带说明:如果您只想检查字符串是否为空,可以使用 strcmp(tagArray[x], "")

已解决:谢谢大家的回复。每个人的贡献都提供了帮助并进行了研究,但亚历山大的评论和选择的答案相结合才对我有所帮助。我认为 C 中不存在列表。只有数组。很高兴知道 GTK 提供了一个 GList。

无论如何..经过多次哀号和咬牙切齿,(这实际上是我尝试学习低级 C 的第 5 天,我是 C# 人)我能够修改提供的答案以适合我的解决方案.

第 1 步:将复选按钮添加到列表中,以便稍后检索它们。现有代码只增加了一行:

for (int x = 0; x <= NUMBER_OF_STRING; x++)
{
    if (tagArray[x] != NULL && strcmp(tagArray[x], "[=10=]"))
    {
        dynamic_checkBox = gtk_check_button_new_with_label(tagArray[x]);
        gtk_container_add(GTK_CONTAINER(flowBox), dynamic_checkBox);
        g_signal_connect(dynamic_checkBox, "toggled" G_CALLBACK(check_state), (gpointer)tagArray[x]);
        checkButtonList = g_list_insert(checkButtonList, dynamic_checkBox, -1);
    }
}

第 2 步:遍历复选按钮列表并取消选中每一个:

static void uncheck_button_clicked(GtkCheckButton* checkButton, gpointer data)
{

     for (GList *l = checkButtonList; l != NULL; l = l->next)
    {
        GtkWidget *child = l->data;
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(child), FALSE);
    }
    
}