Radio buttons in GTK 4 - preventing toggling off?

The GTK3 to GTK4 migration guide indicates that radio buttons should be replaced with toggle buttons which are grouped together. That makes sense, but it allows for behaviour that I don’t want, such as being able to toggle a button off, when the behaviour I want is that there is always exactly a single button that is toggled on (and clicking on it at that point shouldn’t do anything, instead of toggling it off).

To be specific about the problem I am attempting to solve, I want tabs that function like in a browser (or text editor, or image editor, …). There should be precisely one tab selected at all times (unless there are no tabs).

Does anyone have suggestions about how to implement this in GTK 4? I tried making the toggle buttons not sensitive once they are toggled on, but that rendered them completely unresponsive (I’d have to traverse all of the other tabs in the group to ensure they are made sensitive again once a different tab gets selected).

I apologise if I’ve missed anything obvious.

1 Like

Assuming you’re using an action, you can do something like this in your setup.

foreach (button : buttons) {
    button.toggled.connect(() => {
        if (!button.active && button.action_value.equal(action.state))
            button.active = true;
    });
}

That would detect a click on an already active button and re-activate the button. Without an action you’d still do the same, but with some other means to check the button’s value against the enum value stored in the model.

Alternatively, you can use GtkCheckButton. That will take on the appearance and behavior of the old GtkRadioButton when its group property is used, or when its action-name is set to a stateful action.

2 Likes

Thank you, Jason.
I’m not using actions but I’m keeping track separately in my application of which tab is currently selected. I’m giving this a try but still struggling.

At the moment, your approach succeeds in making the toggle button remain active, but when switching between toggle buttons, the previously active toggle button remains active. I’m unsure why that is; possibly some subtlety about the order in which the signal handlers are run…

Edit: I added some logic to specifically disable the previously active button and it all works as expected now. It’s certainly a bit hacky and might break in the future, but I’ve spent several days on this by now so it’ll have to do.

The recommended replacement for radio buttons are grouped checkbuttons, and those behave as you want.

I consider it a bug that grouped toggle buttons don’t.

So the expected behaviour is that clicking on a toggle button that is already active and is part of a group should not do anything, and the fact that this isn’t the case currently is a bug? Is this correct? I can open a ticket on the tracker if so.

I’ve fixed it already.

1 Like

Excellent, thank you very much.

GtkStackSwitcher and AdwViewSwitcher did the right thing previously, I’m guessing there was code there to work around that?

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