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