Python Forum
[WxPython] [SOLVED] [RadioBox] Set default?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[WxPython] [SOLVED] [RadioBox] Set default?
#1
Question 
Hello,

Searching Google or the archives with "RadioBox default" returned no hits.

Do you know of a better way to set the default item in a set of radioboxes?

Thank you.

lblList = ['640','426','256'] 
self.rbox = wx.RadioBox(panel, label = 'Width', choices = lblList, majorDimension = 1, style = wx.RA_SPECIFY_ROWS) 
#right way to set default?
self.rbox.SetSelection(1)
"""
TODO How to avoid magic number?
for index, item in enumerate(fruits):
	print(index, item)
"""
--
Edit: Unless there's a better way:
self.rbox.SetSelection(lblList.index("426"))
Reply
#2
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()
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020