Menu items with radio action

I am trying to figure out how to make a set of menu items which have radio action. My best attempt so far is something along the following lines. First create the action group and add the actions:

auto radiogroup = Gio::SimpleActionGroup::create();
radiogroup->add_action_radio_integer( "One", [binding], 0 );
radiogroup->add_action_radio_integer( "Two", [binding], 1 );
...
insert_action_group( "myradio", radiogroup );

(where I have suppressed the callback binding as it’s not relevant for my question). Then in the XML that I feed to Gtk::Builder I use

<submenu>
  <attribute name='label'>My Radio</attribute>
  <section>
    <item>
       <attribute name='label'>Choice One</attribute>
       <attribute name='action'>myradio.One</attribute>
    </item>
    <item>
      <attribute name='label'>Choice Two</attribute>
       <attribute name='action'>myradio.Two</attribute>
    </item>
  </section>
</submenu>

This compiles and runs fine (without warnings), but the menu items remain grayed-out.

Any suggestions? Or perhaps a document somewhere that I have overlooked that explains this all?

Thanks!
Kasper

Radio items should use the same action, with different targets. I’m not familiar with that glibmm API, but a single add_action_radio_integer() per radio group should work.

In your menu XML, you can set the target attribute differently for each radio item:

       <attribute name="action">myradio.One</attribute>
       <attribute name="target" type="i">0</attribute>
       <attribute name="action">myradio.One</attribute>
       <attribute name="target" type="i">1</attribute>

If that still doesn’t work, what widget are you adding the action group to? It needs to be an ancestor of the menu widget.

Ah, thanks, that helps!

For future reference and anyone else stuck on the same problem: I was under the wrong impression that I should create a Gio::SimpleAction for every possible value of the radio group. But the logic is instead that you create one such action (with the default value),

Glib::RefPtr<Gio::SimpleActionGroup> actiongroup =
    Gio::SimpleActionGroup::create();
 
Glib::RefPtr<Gio::SimpleAction> radio_action = 
    actiongroup->add_action_radio_integer( "MyRadio",  sigc::mem_fun(*this, &MyAppWindow::on_radio_change), 0 );

The actiongroup can contain more actions (not just the radio group). Add this to the app window using

insert_action_group("myapp", actiongroup);

Then the XML lists all the possible values,

<submenu>
  <attribute name='label'>My Radio</attribute>
  <section>
    <item>
       <attribute name='label'>Choice One</attribute>
       <attribute name='action'>myapp.MyRadio</attribute>
       <attribute name='target' type='i'>0</attribute>
    </item>
    <item>
       <attribute name='label'>Choice Two</attribute>
       <attribute name='action'>myapp.MyRadio</attribute>
       <attribute name='target' type='i'>1</attribute>
    </item>
  </section>
</submenu>

Finally, in the callback, you need to confirm the change in the radio group state:

void MyAppWindow::on_radio_change(int num)
   {
   radio_action->set_state(Glib::Variant<int>::create(num));
   }

I’ll also note that GtkApplicationWindow is also a GApplicationMap, so you don’t need the separate action group. You can add the action directly to the window, where its prefix would be win.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.