You could subclass RadioBox to make it more string friendly, using the item names instead of index values to get or set the selection.
import wx
class RadioBox(wx.RadioBox):
"""A wx RadioBox where you can SetSelection using a string."""
def SetSelection(self, value: int | str | None):
"""Set selection using index or string."""
if isinstance(value, str):
value = self.FindString(value)
if isinstance(value, int):
super().SetSelection(value)
def GetSelectedString(self) -> str:
"""Return the string for the current selection."""
return self.GetString(self.GetSelection())
class Demo(wx.Frame):
"""Demonstrate modified RadioBox."""
def __init__(self, parent, title):
super().__init__(parent, title=title)
panel = wx.Panel(self)
self.widths = {"640": 640, "426": 426, "256": 256}
self.width = RadioBox(
panel, label="Width", choices=list(self.widths), majorDimension=1, style=wx.RA_SPECIFY_ROWS
)
self.width.SetSelection("256")
self.width.Bind(wx.EVT_RADIOBOX, self.selection_changed)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(self.width, 0, wx.ALL | wx.CENTER, 10)
panel.SetSizer(vbox)
self.Centre()
self.Show(True)
def selection_changed(self, arg) -> None:
"""Print the selected item."""
print(self.widths[self.width.GetSelectedString()])
app = wx.App()
demo = Demo(None, "IntegerRadioBox")
app.MainLoop()This eliminates having to know anything about indices, but you need to write code to convert radio box strings to their associate value.
A better solution is have the radio box do the conversion. DictionaryRadioBox has a dictionary for converting between the selection and the value for the selection. The keys are the strings that appear in the radio box. The dictionary values are the value associated with that selection. Keys have to be str, but values can be anything that is hashable. GetValue() returns the selected value, not index or name string. SetValue() sets the selection based on dictionary values. In the example below, two DictionaryRadioBoxes are used to make an equation solver.
import wx
class DictionaryRadioBox(wx.RadioBox):
"""A wx RadioBox for selecting from a dictionary of choices."""
def __init__(self, *args, choices={}, default=None, **kwargs) -> None:
self.choices = choices
self.rev_choices = {value: key for key, value in choices.items()}
super().__init__(*args, choices=list(self.choices), **kwargs)
if default is not None:
self.SetValue(default)
def SetSelection(self, selection):
"""Set selection using item index or string."""
if isinstance(selection, str):
selection = self.FindString(selection)
if isinstance(selection, int):
super().SetSelection(selection)
def GetSelectedString(self):
"""Return string of selected item."""
return self.GetString(self.GetSelection())
def GetValue(self):
"""Return dictionary value of current selection."""
return self.choices[self.GetSelectedString()]
def SetValue(self, value):
"""Set selection using item value."""
self.SetSelection(self.rev_choices[value])
# Declare some functions to use in Demo.
def sqr(x):
return x * x
def cube(x):
return x**3
def sqrt(x):
return x**0.5
class Demo(wx.Frame):
"""Demonstrate DictionaryRadioBox."""
def __init__(self, parent, title):
super().__init__(parent, title=title)
panel = wx.Panel(self)
# Radio box of functions.
self.functions = DictionaryRadioBox(
panel,
label="Functions",
choices={"x\u00b2": sqr, "x\u00b3": cube, "\u221ax": sqrt},
default=cube,
majorDimension=1,
style=wx.RA_SPECIFY_ROWS,
)
self.functions.Bind(wx.EVT_RADIOBOX, self.evaluate)
# Radio box of function arguments.
self.x = DictionaryRadioBox(
panel,
label="x",
choices={str(i): float(i) for i in range(1, 11)},
default=2.0,
majorDimension=5,
style=wx.RA_SPECIFY_COLS,
)
self.x.Bind(wx.EVT_RADIOBOX, self.evaluate)
# Display function result
self.result = wx.StaticText(panel, label="_" * 20, style=wx.ALIGN_CENTER_HORIZONTAL)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(self.functions, 0, wx.ALL | wx.CENTER, 10)
vbox.Add(self.x, 0, wx.ALL | wx.CENTER, 10)
vbox.Add(self.result, 0, wx.ALL | wx.CENTER, 10)
panel.SetSizer(vbox)
self.Show(True)
self.evaluate(None)
def evaluate(self, _):
"""Display result of function."""
x = self.x.GetValue() # Get float value of x
func = self.functions.GetValue() # Get function to evaluate
func_name = self.functions.GetSelectedString().replace("x", str(x)) # Get the str for the function to use as output.
self.result.SetLabel(f"{func_name} = {func(x)}") # Call function and display result.
app = wx.App()
demo = Demo(None, "DictionaryRadioBox")
app.MainLoop()