Как получить доступ к динамически созданной контрольной кнопке GTK на обычном C

#c #checkbox #dynamic #gtk3 #children

#c #флажок #динамический #gtk3 #дочерние элементы

Вопрос:

Я создал программу, которая выводит теги в формате CSV на основе контрольных кнопок.. Их МНОГО, поэтому имеет смысл создавать их программно.. В этом смысле мне это удалось, но я так и не смог понять, как получить их проверенное состояние, поскольку вы не можете получить к ним доступ, как к обычным контрольным кнопкам. Я работал над этим, но теперь, перейдя к фазе «полировки» моей программы, я бы ОЧЕНЬ хотел иметь возможность сбросить форму, сняв их все, и я не могу понять, как получить к ним доступ .. Во-первых, вот как контрольные кнопки создаются динамически:

         for (int x = 0; x <= NUMBER_OF_STRING; x  )
        {
            if (tagArray[x] != NULL amp;amp; strcmp(tagArray[x], ""))
            {
                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]);
            }
        }
  

Так что это работает просто отлично.. Я смог использовать небольшой «взлом», создав дополнительный массив символов и поместив туда строки ‘true’ или ‘false’ и используя strcmp (), чтобы в основном записать свое собственное проверенное / непроверенное состояние в массив с данными gpointer, но, как и в большинстве взломов, если вы не делаетеэто правильно, что он возвращается, чтобы получить тебя.. Теперь я не могу понять, как снять все флажки и сбросить форму..

 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 дня гуглю и бьюсь головой о стену, но безрезультатно. Заранее спасибо.

Комментарии:

1. Что вам, вероятно, нужно, так это GtkCellRendereToggle . В любом случае, пожалуйста, отредактируйте свой вопрос с помощью примера кода.

2. Как насчет размещения всех флажков в хеш-таблице с tagArray [x] в качестве ключа? Если вы хотите снять все из них, просто выполните итерацию по хэш-таблице.

Ответ №1:

Прежде всего, не имеет смысла использовать глобальное GtkWidget* или GtkCheckButton* , поскольку у вас их все равно несколько, поэтому каждый раз, когда вы создаете новое, оно перезаписывает старое значение.

Далее, есть 2 способа получить доступ к этим кнопкам:

  • Как Александр предложил в комментариях, вы можете сохранить список 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], "") , если просто хотите проверить, является ли строка пустой

Ответ №2:

РЕШАЕМАЯ: спасибо всем за ваши ответы. Вклад каждого помог и был изучен, но мне помогло сочетание комментария Александра и выбранного ответа. Я не думал, что списки существуют в C. Только массивы.. Полезно знать, что GTK предлагает GList..

В любом случае .. после долгих стенаний и скрежета зубов (это буквально мой 5-й день, когда я пытаюсь выучить низкоуровневый C, я парень с #) Я смог изменить предоставленный ответ в соответствии с моим решением.

Шаг 1. Добавьте контрольные кнопки в список, чтобы их можно было получить позже. В существующий код была добавлена только одна строка:

 for (int x = 0; x <= NUMBER_OF_STRING; x  )
{
    if (tagArray[x] != NULL amp;amp; strcmp(tagArray[x], ""))
    {
        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);
    }
    
}