I'm trying my hand at GTK UI and need help with the following problem ; I couldn't find too much material about it online.
Using GTK 3, in the C language and on Linux, I am trying to generate a UI list of radio buttons that would all belong to the same group.
I thought this would work:
void make_projects_list(GtkWidget *projects_grid)
{
int n = 20;
GSList *group;
for (int i =0; i<n; i++)
{
GtkWidget *radio;
char label[3];
snprintf(label, 3, "%d", i);
if (i==0)
{
radio = gtk_radio_button_new_with_label(NULL, label);
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
}
else
{
radio = gtk_radio_button_new_with_label(group, label);
}
gtk_grid_insert_row(GTK_GRID(projects_grid), i);
gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1);
}
}
If the radio button is the first to be created, I summon it with "NULL" as a first parameter so that GTK creates a group for it, then all the other buttons would get assigned to that group.
However when I run this code along with the rest of my program none of the buttons seem to belong to the same group, as they're almost all toggleable independently of one another, except for button 0, with remains toggled even when I click it.
Would appreciate any help since I'm obviously missing something. All the examples I could find online create a distinct variable for every radio button so I'm wondering if what I'm trying to achieve is even possible.
Here's a sample to reproduce (the window it spawns is tiny by fault but you can expand it)
#include<gtk/gtk.h>
#include<stdio.h>
void make_projects_list(GtkWidget *projects_grid)
{
int n = 20;
GSList *group;
for (int i =0; i<n; i++)
{
GtkWidget *radio;
char label[3];
snprintf(label, 3, "%d", i);
if (i==0)
{
radio = gtk_radio_button_new_with_label(NULL, label);
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
}
else
{
radio = gtk_radio_button_new_with_label(group, label);
}
gtk_grid_insert_row(GTK_GRID(projects_grid), i);
gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1);
}
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
GtkWidget *grid;
GError *error = NULL;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
if (gtk_builder_add_from_file(builder, "build.ui", &error) == 0)
{
g_printerr("Error loading file: %s\n", error->message);
g_clear_error(&error);
return 1;
}
window = GTK_WIDGET (gtk_builder_get_object(builder, "window"));
grid = GTK_WIDGET (gtk_builder_get_object(builder, "grid"));
gtk_builder_connect_signals(builder, NULL);
make_projects_list(grid);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
build.ui:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow" id="window">
<property name="can-focus">False</property>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkViewport" id="viewport">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
I am aware I should not use Glade. In this precise context I have elected to use it as a shortcut as I need to get this particular application done in a timely manner for school.
When using the new radio button interfaces that use the group, the group must be re-fetched each time so that the group list is correct. The old group list is no longer valid after another radio button is added to the group. Your updated code looks like:
void make_projects_list(GtkWidget *projects_grid)
{
int n = 20;
GSList *group = NULL;
for (int i =0; i<n; i++)
{
GtkWidget *radio;
char label[3];
snprintf(label, 3, "%d", i);
radio = gtk_radio_button_new_with_label(group, label);
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), i==0?1:0);
gtk_grid_insert_row(GTK_GRID(projects_grid), i);
gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1);
}
}