3

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.

1
  • Interesting. I have not dug into why. I use gtk_radio_button_new_with_label_from_widget in my code, and that does work. I may look at this more tomorrow. Commented Jan 11 at 1:21

1 Answer 1

0

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);
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.