Checkboxes and Radio Buttons in wxPython

In this article, we will focus on two basic controls and a few relatives: checkboxes and radio buttons. Both controls give the user a variety of options and yet him or her choose anywhere from one to all of them.

This article assumes that you have basic knowledge of wxPython – how to create a frame, populate it with controls and organize them. Make sure you understand these tasks before you dive into this article.

wxCheckBox

Checkboxes are useful in applications. Besides looking nice and neat, they can be used for more than one purpose. For example, in one application, checkboxes could allow a user to select all the items that apply, and in another application, checkboxes could give the user the option to turn things on and off. They are also very easy to work with and aren’t over-complicated by too many methods and events.

Let’s take a look at a very simple application that uses checkboxes to gather input from the user:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘Survey’, size = ( 400, 200 ) )

      # Create a panel to house everything

      self.panel = wxPanel ( self, -1 )

      # Create a wxGridBagSizer to organize our widgets

      self.sizer = wxGridBagSizer ( 5, 5 )

      # Create a label for our application

      self.label = wxStaticText ( self.panel, -1, ‘What electronics do you plan to buy in the next year?’ +

                                                  ‘nCheck all that apply.’, style = wxTE_CENTER )

      # Create a few wxCheckBox instances

      self.camera = wxCheckBox ( self.panel, -1, ‘Digital Camera’ )

      self.music = wxCheckBox ( self.panel, -1, ‘Music-related Device’ )

      self.hardware = wxCheckBox ( self.panel, -1, ‘Computer Hardware’ )

      self.television = wxCheckBox ( self.panel, -1, ‘Television’ )

      self.dvd = wxCheckBox ( self.panel, -1, ‘DVDPlayer’ )

      self.other = wxCheckBox ( self.panel, -1, ‘Other’ )

      # Create a button

      self.button = wxButton ( self.panel, 100, ‘Submit’ )

      # Catch a click to the button

      EVT_BUTTON ( self.panel, 100, self.submit )

      # Add everything to the sizer

      self.sizer.Add ( self.label, ( 0, 0 ), ( 1, 3 ), wxALIGN_CENTER )

      self.sizer.Add ( self.camera, ( 1, 0 ) )

      self.sizer.Add ( self.music, ( 1, 1 ) )

      self.sizer.Add ( self.hardware, ( 1, 2 ) )

      self.sizer.Add ( self.television, ( 2, 0 ) )

      self.sizer.Add ( self.dvd, ( 2, 1 ) )

      self.sizer.Add ( self.other, ( 2, 2 ) )

      self.sizer.Add ( self.button, ( 3, 0 ), ( 1, 3 ), wxALIGN_CENTER )

      # Center everything

      self.horizontal = wxBoxSizer ( wxHORIZONTAL )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.horizontal.Add ( self.sizer )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.vertical = wxBoxSizer ( wxVERTICAL )

      self.vertical.Add ( ( 0, 0, ), 1 )

      self.vertical.Add ( self.horizontal, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 0, 0 ), 1 )

      # Attach the sizer to the panel

      self.panel.SetSizerAndFit ( self.vertical )

      self.Show ( True )

   # This method is triggered when the button is clicked

   # It checks whether or not each checkbox is clicked

   def submit ( self, event ):

      message = ‘You plan to get the following items in the next year:’

      # Check whether or not each checkbox is clicked

      # If one is, add a string to the message variable

      if self.camera.GetValue():

         message = message + ‘nDigital Camera’

      if self.music.GetValue():

         message = message + ‘nMusic-related Device’

      if self.hardware.GetValue():

         message = message + ‘nComputer Hardware’

      if self.television.GetValue():

         message = message + ‘nTelevision’

      if self.dvd.GetValue():

         message = message + ‘nDVD Player’

      if self.other.GetValue():

         message = message + ‘nOther’

      # Display a dialog with the results

      dialog = wxMessageDialog ( self, message, ‘Results’, style = wxOK )

      dialog.ShowModal()

      dialog.Destroy()

application = wxPySimpleApp()

Window()

application.MainLoop()

It is also possible to catch a click on a checkbox and set the value of the checkbox. We’ll create a simple application that combines both of these functions:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘Checkbox Test’, size = ( 200, 200 ) )

      # Create a panel

      self.panel = wxPanel ( self, -1 )

      # Create a vertical sizer

      self.vertical = wxBoxSizer ( wxVERTICAL )

      # Add a space

      self.vertical.Add ( ( 0, 0 ), 1 )

      # Create and add two checkboxes

      self.first = wxCheckBox ( self.panel, 1, ‘First’ )

      self.second = wxCheckBox ( self.panel, 2, ‘Second’ )

      self.vertical.Add ( self.first, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.second, 0, wxALIGN_CENTER )

      # Catch events

      EVT_CHECKBOX ( self.panel, 1, self.firstHandle )

      EVT_CHECKBOX ( self.panel, 2, self.secondHandle )

      # Add another space

      self.vertical.Add ( ( 0, 0 ), 1 )

      # Center it with a horizontal sizer

      self.horizontal = wxBoxSizer ( wxHORIZONTAL )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.horizontal.Add ( self.vertical, 0, wxALIGN_CENTER )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      # Add the sizer

      self.panel.SetSizerAndFit ( self.horizontal )

      self.Show ( True )

   # This method unchecks the other checkbox if it is checked

   def firstHandle ( self, event ):

      self.second.SetValue ( False )

   # This method does the same thing

   def secondHandle ( self, event ):

      self.first.SetValue ( False )

application = wxPySimpleApp()

Window()

application.MainLoop()

A normal checkbox has two states. It is possible, however, to create a checkbox with three states:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘Checkbox Test’, size = ( 200, 200 ) )

      # Create a panel

      self.panel = wxPanel ( self, -1 )

      # Create a checkbox with three states

      self.checkbox = wxCheckBox ( self.panel, 1, ‘Tri-state border’, style = wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER )

      # Catch a click

      EVT_CHECKBOX ( self.panel, 1, self.handle )

      self.Show ( True )

   # Handle a click event

   def handle ( self, event ):

      # Print the value of the checkbox

      print self.checkbox.Get3StateValue()

application = wxPySimpleApp()

Window()

application.MainLoop()

{mospagebreak title=wxCheckListBox}

The wxCheckListBox is a combination of wxCheckBox and wxListBox. It is basically a list of checkboxes that users can click. It’s useful if you have a large amount of checkboxes. Let’s create an application that shows off wxCheckListBox‘s features:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘Dinner’, size = ( 300, 300 ) )

      # Create a status bar

      self.CreateStatusBar()

      # Create a panel

      self.panel = wxPanel ( self, -1 )

      # Create a label

      self.label = wxStaticText ( self.panel, -1, ‘Configure your dinner:’ )

      # Define a list of items to place in the wxCheckListBox

      self.dinner = [ 'Ravioli', 'Apple Pie', 'Dr. Pepper', 'Soup', 'Salad', 'Ham Sandwich', 'Pizza',

                      'Macaroni and Cheese', 'Carrot Cake', 'Spinach', 'Potato Salad ( Southern Style )' ]

      # Create a wxCheckListBox

      self.box = wxCheckListBox ( self.panel, 100, size = ( 150, 100 ), choices = self.dinner, style = wxLB_HSCROLL )

      # Hook up an event handling method

      EVT_CHECKLISTBOX ( self.panel, 100, self.clickHandler )

      # Create a button

      self.button = wxButton ( self.panel, 200, ‘Prepare’ )

      # Hook up an event handling method

      EVT_BUTTON ( self.panel, 200, self.buttonHandler )

      # Create two sizers to make everything pretty

      # The usual

      self.vertical = wxBoxSizer ( wxVERTICAL )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.vertical.Add ( self.label, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.box, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.button, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.horizontal = wxBoxSizer ( wxHORIZONTAL )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.horizontal.Add ( self.vertical, 0, wxALIGN_CENTER )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      # Attach the sizer

      self.panel.SetSizerAndFit ( self.horizontal )

      self.Show ( True )

   # This method is called when an item is clicked

   def clickHandler ( self, event ):

      if self.box.IsChecked ( event.GetSelection() ):

         message = ‘ will be prepared.’

      else:

         message = ‘ will not be prepared.’

      # Update the status bar of the window

      self.SetStatusText ( self.box.GetString ( event.GetSelection() ) + message )

   # This method will be called when the button is clicked

   def buttonHandler ( self, event ):

      message = ‘The following items have been prepared:’

      # Check to see what has been selected and what has not

      x = 0

      for choice in self.dinner:

         if self.box.IsChecked ( x ):

            message = message + ‘n’ + choice

         x = x + 1

      # Display a dialog

      dialog = wxMessageDialog ( self, message, ‘Your dinner is ready.’, style = wxOK )

      dialog.ShowModal()

      dialog.Destroy()

application = wxPySimpleApp()

Window()

application.MainLoop()

{mospagebreak title=wxRadioButton}

Radio buttons are useful when you want the user to select one item out of a list of multiple items. Alternatively, the user can check a single radio button that cannot be unchecked. A group of radio buttons is started by setting the style wxRB_GROUP on the first button, and a lone radio button is created by setting wxRB_SINGLE as the style. Let’s put together an application that uses radio buttons:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘Ballot’ )

      # Create a panel, like we always do

      self.panel = wxPanel ( self, -1 )

      # Create a grid layout

      self.sizer = wxGridBagSizer ( 2, 10 )

      # Create one group of buttons ( plus a label ) and add them

      # We mark the beginning of the group with wxRB_GROUP

      self.president1 = wxRadioButton ( self.panel, -1, ‘CharlesFagundes’, style = wxRB_GROUP )

      self.president2 = wxRadioButton ( self.panel, -1, ‘TerriWells’ )

      self.sizer.Add ( wxStaticText ( self.panel, -1, ‘President’ ), ( 0, 0 ) )

      self.sizer.Add ( self.president1, ( 1, 0 ) )

      self.sizer.Add ( self.president2, ( 2, 0 ) )

      # Create another group of radio buttons

      self.senator1 = wxRadioButton ( self.panel, -1, ‘Peyton McCullough’, style = wxRB_GROUP )

      self.senator2 = wxRadioButton ( self.panel, -1, ‘Alejandro Gervasio’ )

      self.senator3 = wxRadioButton ( self.panel, -1, ‘Jagadish Chatarji’ )

      self.senator4 = wxRadioButton ( self.panel, -1, ‘Michael Swanson’ )

      self.sizer.Add ( wxStaticText ( self.panel, -1, ‘Senator’ ), ( 0, 1 ) )

      self.sizer.Add ( self.senator1, ( 1, 1 ) )

      self.sizer.Add ( self.senator2, ( 2, 1 ) )

      self.sizer.Add ( self.senator3, ( 3, 1 ) )

      self.sizer.Add ( self.senator4, ( 4, 1 ) )

      # Create yet another group of radio buttons

      # These will not be in a group

      # We’ll also create a button, which will be activated if both boxes are checked

      self.term1 = wxRadioButton ( self.panel, 1, ‘This is my only ballot.’, style = wxRB_SINGLE )

      self.term2 = wxRadioButton ( self.panel, 1, ‘I swear it is!’, style = wxRB_SINGLE )

      self.button = wxButton ( self.panel, 2, ‘Submit’ )

      self.button.Disable()

      self.sizer.Add ( wxStaticText ( self.panel, -1, ‘Agreement’ ), ( 0, 2 ) )

      self.sizer.Add ( self.term1, ( 1, 2 ) )

      self.sizer.Add ( self.term2, ( 2, 2 ) )

      self.sizer.Add ( self.button, ( 3, 2 ), ( 2, 1 ), wxALIGN_CENTER )

      # Hook up events to the three controls above

      EVT_RADIOBUTTON ( self.panel, 1, self.confirm )

      EVT_BUTTON ( self.panel, 2, self.vote )

      # Attach our sizer to our panel

      self.panel.SetSizerAndFit ( self.sizer )

      # Resize the window

      self.sizer.Fit ( self )

      self.Show ( True )

   # This will check to see if term1 and term2 have both been clicked

   # If so, the button will be disabled

   def confirm ( self, event ):

      if ( self.term1.GetValue() == True ) & ( self.term2.GetValue() == True ):

         self.button.Enable()

   # Here, we will send a message to the user and reset everything

   def vote ( self, event ):

      # Show a dialog

      dialog = wxMessageDialog ( self, ‘Thank you for your vote.’, ‘Thank You’, style = wxOK )

      dialog.ShowModal()

      dialog.Destroy()

      # Reset things

      self.president1.SetValue ( True )

      self.senator1.SetValue ( True )

      self.term1.SetValue ( False )

      self.term2.SetValue ( False )

      self.button.Disable()

application = wxPySimpleApp()

Window()

application.MainLoop()

Simple, huh?

{mospagebreak title=wxRadioBox}

By using wxRadioBox, it is possible to create a boxed group of radio buttons. The result looks like a group of radio buttons surrounded by a wxStaticBox and is visually appealing.The creation of a wxRadioBox is incredibly simple because the labels of each radio box are passed in the form of a list. The rows and columns of the wxRadioBox are then determined by the majorDimension variable and either the wxRA_SPECIFY_ROWS or the wxRA_SPECIFY_COLS style. If wxRA_SPECIFY_ROWS is passed, the value in majorDimension will be the number of rows. The same thing works for wxRA_SPECIFY_COLS and columns. Let’s take a closer look at how it all works:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘wxRadioBox’, size = ( 300, 300 ) )

      # Create a status bar

      self.CreateStatusBar()

      # Create a panel

      self.panel = wxPanel ( self, -1 )

      # Create a list of radio buttons

      self.radioList = [ 'This', 'Is', 'A', 'Box', 'Full', 'Of', 'Radio', 'Buttons' ]

      # Create a wxRadioBox with two rows

      self.radioBox1 = wxRadioBox ( self.panel, 1, ‘Radio Box 1′, choices = self.radioList, majorDimension = 2, style = wxRA_SPECIFY_ROWS )

      # Create a wxRadoiBox with two columns

      self.radioBox2 = wxRadioBox ( self.panel, 1, ‘Radio Box 2′, choices = self.radioList, majorDimension = 2, style = wxRA_SPECIFY_COLS )

      # Tie in methods to handle a click

      EVT_RADIOBOX ( self.panel, 1, self.radioClick )

      # Center everything

      self.vertical = wxBoxSizer ( wxVERTICAL )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.vertical.Add ( self.radioBox1, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.radioBox2, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.horizontal = wxBoxSizer ( wxHORIZONTAL )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.horizontal.Add ( self.vertical, 0, wxALIGN_CENTER )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      # Attach the sizer

      self.panel.SetSizerAndFit ( self.horizontal )

      self.Show ( True )

   def radioClick ( self, event ):

      # Get the wxRadioBox

      radioBox = event.GetEventObject()

      # Get the index of the selected button

      radioIndex = radioBox.GetSelection()

      # Get the string of the selected button

      radioString = radioBox.GetStringSelection()

      # Update the status bar

      self.SetStatusText ( str ( radioIndex ) + ‘: ‘ + radioString )

application = wxPySimpleApp()

Window()

application.MainLoop()

There are other things you can do with a wxRadioBox, too. You can disable a wxRadioBox, find the location of a label, count the buttons, get the label of a button, set the label of a button and set the current selection. Let’s take a look at these features:

from wxPython.wx import *

class Window ( wxFrame ):

   def __init__ ( self ):

      wxFrame.__init__ ( self, None, -1, ‘wxRadioBox Features’, size = ( 300, 300 ) )

      # Create a panel

      self.panel = wxPanel ( self, -1 )

      # Create a wxRadioBox to experiment on

      self.box = wxRadioBox ( self.panel, 100, ‘A Radio Box’, choices = [ 'A', 'B', 'C', 'D' ], majorDimension = 2, style = wxRA_SPECIFY_COLS )

      # Handle a click with a method

      EVT_RADIOBOX ( self.panel, 100, self.radioClick )

      # Create a label to count the items in our wxRadioBox

      self.count = wxStaticText ( self.panel, -1, ‘Count: ‘ + str ( self.box.GetCount() ) )

      # Create a label to display the label of the currently selected button

      self.label = wxStaticText ( self.panel, -1, ‘Label: ‘ + str ( self.box.GetItemLabel ( self.box.GetSelection() ) ) )

      # Create a label to display the position of the radio button whose label is “A”:

      self.find = wxStaticText ( self.panel, -1, ‘”A”: ‘ + str ( self.box.FindString ( ‘A’ ) ) )

      # Create a button that disables the entire wxRadioBox and attach a handler

      self.disableBoxButton = wxButton ( self.panel, 200, ‘Disable Box’ )

      EVT_BUTTON ( self.panel, 200, self.disableBox )

      # Create a button that disables the currently selected item and attach a handler

      self.disableItemButton = wxButton ( self.panel, 300, ‘Disable Item’ )

      EVT_BUTTON ( self.panel, 300, self.disableItem )

      # Create a button that changes the label of the currently selected item and attach a handler

      self.changeLabelButton = wxButton ( self.panel, 400, ‘Change Label’ )

      EVT_BUTTON ( self.panel, 400, self.changeLabel )

      # Center things in two sizers

      self.vertical = wxBoxSizer ( wxVERTICAL )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.vertical.Add ( self.box, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.count, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.label, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.find, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.disableBoxButton, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.disableItemButton, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 5, 5 ), 0 )

      self.vertical.Add ( self.changeLabelButton, 0, wxALIGN_CENTER )

      self.vertical.Add ( ( 0, 0 ), 1 )

      self.horizontal = wxBoxSizer ( wxHORIZONTAL )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      self.horizontal.Add ( self.vertical, 0, wxALIGN_CENTER )

      self.horizontal.Add ( ( 0, 0 ), 1 )

      # Attach our horizontal sizer

      self.panel.SetSizerAndFit ( self.horizontal )

      self.Show ( True )

   # This method is called when a radio button is clicked

   def radioClick ( self, event ):

      # Update the label label

      self.label.SetLabel ( ‘Label: ‘ + str ( self.box.GetItemLabel ( self.box.GetSelection() ) ) )

   # This method is called when the “Disable Box” button is clicked

   def disableBox ( self, event ):

      # Disable the wxRadioBox

      self.box.Enable ( False )

   # This method is called when the “Disable Item” button is clicked

   def disableItem ( self, event ):

      # Disable the currently selected item

      self.box.EnableItem ( self.box.GetSelection(), False )

   # This method is called when the “Set Label” button is clicked

   def changeLabel ( self, event ):

      # Set the label of the currently selected button to “Q”

      self.box.SetItemLabel ( self.box.GetSelection(), ‘Q’ )

      # Update the find label

      self.find.SetLabel ( ‘”A”: ‘ + str ( self.box.FindString ( ‘A’ ) ) )

application = wxPySimpleApp()

Window()

application.MainLoop()

Conclusion

Several “box” controls are offered in wxPython, and they can serve multiple purposes as I mentioned earlier. It’s all up to your creativity. These controls are very simple to use, featuring only a few methods and styles, yet they offer you a large amount of flexibility. These controls can improve your applications when necessary, pleasing their users – the goal of your graphical user interfaces.

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan