Stateful SimpleAction with RadioMenuItem no state-change or activate signal?

I am trying to use GAction with a couple Gtk.RadioMenu but when I select one of them it’s not setting the state nor do I see any changes on the SimpleAction. I know the action and the Gtk.RadioMenu(s) are linked as the default state is set correctly. What I am missing here?

Example below
Thx

UI_DATA = r"""
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <object class="GtkApplicationWindow" id="appwindow">
    <property name="width-request">200</property>
    <property name="height-request">200</property>
    <property name="can-focus">False</property>
    <property name="icon-name">applications-utilities</property>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkMenuBar">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkMenuItem" id="r_menu">
                <property name="visible">True</property>
                <property name="can-focus">False</property>
                <property name="label" translatable="yes">Radio Menu</property>
                <property name="use-underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu">
                    <property name="visible">True</property>
                    <property name="can-focus">False</property>
                    <child>
                      <object class="GtkRadioMenuItem" id="r_one">
                        <property name="visible">True</property>
                        <property name="can-focus">False</property>
                        <property name="action-name">app.radio</property>
                        <property name="action-target">'one'</property>
                        <property name="label" translatable="yes">Radio One</property>
                        <property name="use-underline">True</property>
                        <property name="draw-as-radio">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkRadioMenuItem" id="r_two">
                        <property name="visible">True</property>
                        <property name="can-focus">False</property>
                        <property name="action-name">app.radio</property>
                        <property name="action-target">'two'</property>
                        <property name="label" translatable="yes">Radio Two</property>
                        <property name="use-underline">True</property>
                        <property name="draw-as-radio">True</property>
                        <property name="group">r_one</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
"""

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gio, GLib, Gtk


class RadioApp(Gtk.Application):
    def __init__(self):
        super().__init__(
            application_id="org.radiotest",        
            flags=Gio.ApplicationFlags.FLAGS_NONE)

        self.window = None
        self.builder = builder = Gtk.Builder.new_from_string(UI_DATA, -1)

    def do_startup(self):
        Gtk.Application.do_startup(self)

        radio_action = Gio.SimpleAction.new_stateful(
            "radio",
            GLib.VariantType.new("s"),
            GLib.Variant("s", "one"))

        self.add_action(radio_action)

        radio_action.connect("activate", self._activate)
        radio_action.connect("change-state", self._change_state)

    def do_activate(self):
        if self.window is None:
            self.window = self.builder.get_object("appwindow")
            self.window.set_application(self)
        
        self.window.present()
    
    def _activate(self, *args, **kwarg):
        print(f"{args} {kwargs}")
    
    def _change_state(self, *args, **kwarg):
        print(f"{args} {kwargs}")

app = RadioApp()
app.run()

Maybe the combination of GAction with GtkMenu is not the best choice? I think we had old GtkAction and old GtkMenu, and now have GAction and GMenu. And we have GTK4 now! For GTK4 radio buttons seems to work fine, I created a Nim example once, see GTK4 for Graphical User Interfaces. Should be very similar in Python or C language.

If I was writing an new application that would be my choice as well. But I am dealing with a codebase that is now close to being 15 years old.

Sure, but GAction is supposed to work with “old” buttons and menu’s and they do for the buttons and menu’s I already converted. Just this one isn’t.

I’ll experiment with a GMenu to see if that works but right now I don’t really want to port all the dynamic menu’s we have to GMenu.

1 Like

A GMneu does work but I can’t use that right now. So if anyone has an idea why the Gtk.RadioMenuItem does not make the Gio.SimpleAction emit activate/change-state please help. Example code in OP.

GtkRadioMenuItem and friends don’t really work with actions: they are legacy API for people using widgets and widget signals.

Internally, GTK does not use GtkRadioMenuItem widgets when using gtk_menu_new_from_model(); menus constructed from menu models and actions are built around a private GtkMenuItem subclass that matches the model item.

The issue is that GtkMenuItem implements the GtkActionable interface in order to make some things works with actions, but GtkCheckMenuItem and GtkRadioMenuItem don’t do anything with it.

If you’re using real menu widgets to construct your menus with GTK3 I am afraid you will need to keep using menu item signals instead of actions. The alternative is to port your menus to GMenu.

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