Introduction

Accelerator keys are often a more efficient way of interacting with a GUI that are mouse gestures. However, wxPython does not appear to offer a direct way of associating the label of a textbox, or of another control, with the control itself.

This recipe shows how to associate the accelerator keys implied by a collection of static labels with the appropriate controls in such a way that, when an accelerator key is pressed the associated control gains focus.

What Objects are Involved

wxStaticText, for the control labels wxTextCtrl, wxComboBox and wxCheckBox, as examples of controls that may be labelled with wxStaticText

wxAcceleratorTable, which is wxPython's container for information about accelerators and their associated controls.

Process Overview

In the following example:
  • the series of controls, including a combo box, some edit boxes and so on, are created first
  • a class, called AccumAcceleratorTable, is instantiated that will

  • the series of static labels corresponding to the controls are created, and information about the associations accumulated using the aforementioned class instance
  • the accumulated information is made available for the duration of the script's execution.
  • Note that the method called focusHandler uses information that is accumulated in a dictionary to decide which control is to receive focus based on incoming menu event information.

    Special Concerns

    My main concern is that I might have failed to notice machinery that is already available in wxPython for doing this.

    Code Sample

       1 from wxPython.wx import *
       2 
       3 from re import compile,IGNORECASE
       4 
       5 class mainWindow(wxFrame):
       6     def __init__(self,parent,id,title):
       7         wxFrame.__init__(self,parent,-1,title,size=(500,200),
       8                         style=wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
       9 
      10         self.mainPanel=wxPanel(self,-1)
      11 
      12         # create controls to be subsequently associated with accelerator keys
      13         self.dateEdit=wxTextCtrl(self.mainPanel,wxNewId(),'',(100,20))
      14         self.comboBox=wxComboBox(self.mainPanel,wxNewId() ,'',(100,40),(-1,-1),[],wxCB_DROPDOWN)
      15         self.activityEdit=wxTextCtrl(self.mainPanel,wxNewId(),'',(100,60))
      16         self.hoursEdit=wxTextCtrl(self.mainPanel,wxNewId(),'',(100,80))
      17         self.visitedBox=wxCheckBox(self.mainPanel,wxNewId(),'',(100,100))
      18 
      19         # instance a class that accummulates information about controls and accelerators
      20         accumAcceleratorTable=self.AccumAcceleratorTable(self,self.focusHandler)
      21 
      22         # as each label is created associate appropriate accelerator key with a control
      23         dateEditLabel=wxStaticText(self.mainPanel,-1,accumAcceleratorTable ('&Date',self.dateEdit),(10,20))
      24         clientEditLabel=wxStaticText(self.mainPanel,-1,accumAcceleratorTable ('&Client',self.comboBox),(10,40))
      25         activityEditLabel=wxStaticText(self.mainPanel,-1,accumAcceleratorTable ('&Activity',self.activityEdit),(10,60))
      26         hoursEditLabel=wxStaticText(self.mainPanel,-1,accumAcceleratorTable ('&Hours',self.hoursEdit),(10,80))
      27         visitedEditLabel=wxStaticText(self.mainPanel,-1,accumAcceleratorTable ('&Visited',self.visitedBox),(10,100))
      28 
      29         # put the accummulated accelerator table and associations to use
      30         self.SetAcceleratorTable(wxAcceleratorTable(accumAcceleratorTable.acceleratorTable))
      31         self.idControlDict=accumAcceleratorTable.idControlDict
      32 
      33         self.Show(True)
      34 
      35     def focusHandler(self,event):
      36         self.idControlDict[event.GetId()].SetFocus()
      37 
      38     class AccumAcceleratorTable:
      39         def __init__(self,parent,focusHandler):
      40             self.acceleratorTable=[]
      41             self.idControlDict={ }
      42             self.patt=compile(r'&([a-z])',IGNORECASE)
      43             self.focusHandler=focusHandler
      44             self.parent=parent
      45 
      46         def __call__(self,labelText,controlToFocus):
      47             # find the accelerator key,if any,in the label
      48             result=self.patt.search(labelText)
      49             if result:
      50                 anId=wxNewId()
      51                 self.acceleratorTable.append(( wxACCEL_ALT,ord(result.group(1).upper()),anId))
      52                 self.idControlDict[anId]=controlToFocus
      53                 EVT_MENU(self.parent,anId,self.focusHandler)
      54             return labelText
      55 
      56 class App(wxApp):
      57     def OnInit(self):
      58         frame=mainWindow(None,-1,"Associating labels with controls")
      59         self.SetTopWindow(frame)
      60         return True
      61 
      62 if __name__=="__main__":
      63     app=App(0)
      64     app.MainLoop()
    

    Comments

    If you have comments or suggestions, please contact Bill Bell.

    FocusingControlsWithTheirLabels (last edited 2010-03-20 01:19:41 by cpe-76-173-187-46)

    NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.