text: import wx
  from gooey.gui.components.widgets.bases import BaseWidget
  from gooey.gui.lang.i18n import _
  from gooey.gui.util import wx_util
  from gooey.gui.components.widgets import CheckBox
  from gooey.util.functional import getin, findfirst, merge
  
  
  class RadioGroup(BaseWidget):
  
      def __init__(self, parent, widgetInfo, *args, **kwargs):
          super(RadioGroup, self).__init__(parent, *args, **kwargs)
          self._parent = parent
          self.info = widgetInfo
          self._id = widgetInfo['id']
          self._options = widgetInfo['options']
          self.widgetInfo = widgetInfo
          self.error = wx.StaticText(self, label='')
          self.radioButtons = self.createRadioButtons()
          self.selected = None
          self.widgets = self.createWidgets()
          self.arrange()
          self.applyStyleRules()
  
          for button in self.radioButtons:
              button.Bind(wx.EVT_LEFT_DOWN, self.handleButtonClick)
  
          initialSelection = getin(self.info, ['options', 'initial_selection'], None)
          if initialSelection is not None:
              self.selected = self.radioButtons[initialSelection]
              self.selected.SetValue(True)
          self.handleImplicitCheck()
  
  
      def getValue(self):
          for button, widget in zip(self.radioButtons, self.widgets):
              if button.GetValue():  # is Checked
                  return merge(widget.getValue(), {'id': self._id})
          else:
              # just return the first widget's value even though it's
              # not active so that the expected interface is satisfied
              return self.widgets[0].getValue()
  
      def setErrorString(self, message):
          for button, widget in zip(self.radioButtons, self.widgets):
              if button.GetValue():  # is Checked
                  widget.setErrorString(message)
          self.Layout()
  
      def showErrorString(self, b):
          for button, widget in zip(self.radioButtons, self.widgets):
              if button.GetValue():  # is Checked
                  widget.showErrorString(b)
  
  
      def arrange(self, *args, **kwargs):
          title = getin(self.widgetInfo, ['options', 'title'], _('choose_one'))
          if getin(self.widgetInfo, ['options', 'show_border'], False):
              boxDetails = wx.StaticBox(self, -1, title)
              boxSizer = wx.StaticBoxSizer(boxDetails, wx.VERTICAL)
          else:
              title = wx_util.h1(self, title)
              title.SetForegroundColour(self._options['label_color'])
              boxSizer = wx.BoxSizer(wx.VERTICAL)
              boxSizer.AddSpacer(10)
              boxSizer.Add(title, 0)
  
          for btn, widget in zip(self.radioButtons, self.widgets):
              sizer = wx.BoxSizer(wx.HORIZONTAL)
              sizer.Add(btn,0, wx.RIGHT, 4)
              sizer.Add(widget, 1, wx.EXPAND)
              boxSizer.Add(sizer, 0, wx.ALL | wx.EXPAND, 5)
          self.SetSizer(boxSizer)
  
  
      def handleButtonClick(self, event):
          currentSelection = self.selected
          nextSelection = event.EventObject
  
          if not self.isSameRadioButton(currentSelection, nextSelection):
              self.selected = nextSelection
              self.selected.SetValue(True)
          else:
              # user clicked on an already enabled radio button.
              # if it is not in the required section, allow it to be deselected
              if not self.widgetInfo['required']:
                  self.selected.SetValue(False)
  
          self.applyStyleRules()
          self.handleImplicitCheck()
  
  
      def isSameRadioButton(self, radioButton1, radioButton2):
          return (getattr(radioButton1, 'Id', 'r1-not-found') ==
                  getattr(radioButton2, 'Id', 'r2-not-found'))
  
  
      def applyStyleRules(self):
          """
          Conditionally disabled/enables form fields based on the current
          section in the radio group
          """
          for button, widget in zip(self.radioButtons, self.widgets):
              if isinstance(widget, CheckBox):
                  widget.hideInput()
              if not button.GetValue(): # not checked
                  widget.widget.Disable()
              else:
                  widget.widget.Enable()
  
      def handleImplicitCheck(self):
          """
          Checkboxes are hidden when inside of a RadioGroup as a selection of
          the Radio button is an implicit selection of the Checkbox. As such, we have
          to manually "check" any checkbox as needed.
          """
          for button, widget in zip(self.radioButtons, self.widgets):
              if isinstance(widget, CheckBox):
                  if button.GetValue(): # checked
                      widget.setValue(True)
                  else:
                      widget.setValue(False)
  
  
      def createRadioButtons(self):
          # button groups in wx are statefully determined via a style flag
          # on the first button (what???). All button instances are part of the
          # same group until a new button is created with the style flag RG_GROUP
          # https://wxpython.org/Phoenix/docs/html/wx.RadioButton.html
          # (What???)
          firstButton = wx.RadioButton(self, style=wx.RB_GROUP)
          firstButton.SetValue(False)
          buttons = [firstButton]
  
          for _ in getin(self.widgetInfo, ['data','widgets'], [])[1:]:
              buttons.append(wx.RadioButton(self))
          return buttons
  
      def createWidgets(self):
          """
          Instantiate the Gooey Widgets that are used within the RadioGroup
          """
          from gooey.gui.components import widgets
          return [getattr(widgets, item['type'])(self, item)
                  for item in getin(self.widgetInfo, ['data', 'widgets'], [])]
  