Search code examples
gtkwxpythonwxwidgets

wx.RB_SINGLE makes button unable to be deselected with wxPython


According to the wxWidgets docs1, wxRB_SINGLE requires the programmer to manually handle selecting and deselecting radio buttons from the event handler for the button. However, try as I might, wxPython doesn't let me do that. I tried both directly calling SetValue(False) on the radio button and calling the same function from the wx.EVT_RADIOBUTTON handler, but regardless the radio button stays selected and GetValue() returns True. What gives? Am I fundamentally misunderstanding something about wx.RB_SINGLE?

To clarify, my goal is to have radio buttons that — from the programmer's perspective — function like checkboxes. I want to handle their exact behaviour myself. I don't want any automatic grouping done by wxWidgets.

Here is the code I've been using to debug this:

import wx

class Example(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Example, self).__init__(*args, **kwargs)
        panel = wx.Panel(self)
        rb1 = wx.RadioButton(panel,
                                  label = 'Button 1',
                                  pos = (30, 10),
                                  style=wx.RB_SINGLE
                                  )
        rb2 = wx.RadioButton(panel,
                                  label = 'Button 2',
                                  pos = (30, 30),
                                  style=wx.RB_SINGLE
                                  )
        rb3 = wx.RadioButton(panel,
                                  label = 'Button 3',
                                  pos = (30, 50),
                                  style=wx.RB_SINGLE
                                  )
        rb2.Bind(wx.EVT_RADIOBUTTON, lambda x: rb2.SetValue(False))
        rb2.SetValue(False)


def main():
    app = wx.App()
    ex = Example(None)
    ex.Show(True)
    app.MainLoop()

if __name__ == '__main__':
    main()

For what it's worth, I'm using Ubuntu Linux 22.04 LTS with the GTK (version 3.24.33-1ubuntu2) backend for wxWidgets (via wxPython 4.2.0) running on Python 3.10.6.


Solution

  • This is due to a bug in wxGTK. I submitted a pull request to fix this, which according to the maintainer's comments seems like it will be merged for wxWidgets 3.3.0 (it was also backported to the 3.2 series in 3.2.4). If you're using an older version, I don't know of any workaround unfortunately.