1 import wx
   2 
   3 
   4 class Form(wx.Panel):
   5     ''' The Form class is a wx.Panel that creates a bunch of controls
   6         and handlers for callbacks. Doing the layout of the controls is 
   7         the responsibility of subclasses (by means of the doLayout()
   8         method). '''
   9 
  10     def __init__(self, *args, **kwargs):
  11         super(Form, self).__init__(*args, **kwargs)
  12         self.referrers = ['friends', 'advertising', 'websearch', 'yellowpages']
  13         self.colors = ['blue', 'red', 'yellow', 'orange', 'green', 'purple',
  14                        'navy blue', 'black', 'gray']
  15         self.createControls()
  16         self.bindEvents()
  17         self.doLayout()
  18 
  19     def createControls(self):
  20         self.logger = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_READONLY)
  21         self.saveButton = wx.Button(self, label="Save")
  22         self.nameLabel = wx.StaticText(self, label="Your name:")
  23         self.nameTextCtrl = wx.TextCtrl(self, value="Enter here your name")
  24         self.referrerLabel = wx.StaticText(self,
  25             label="How did you hear from us?")
  26         self.referrerComboBox = wx.ComboBox(self, choices=self.referrers,
  27             style=wx.CB_DROPDOWN)
  28         self.insuranceCheckBox = wx.CheckBox(self,
  29             label="Do you want Insured Shipment?")
  30         self.colorRadioBox = wx.RadioBox(self,
  31             label="What color would you like?",
  32             choices=self.colors, majorDimension=3, style=wx.RA_SPECIFY_COLS)
  33 
  34     def bindEvents(self):
  35         for control, event, handler in \
            [(self.saveButton, wx.EVT_BUTTON, self.onSave),
  36              (self.nameTextCtrl, wx.EVT_TEXT, self.onNameEntered),
  37              (self.nameTextCtrl, wx.EVT_CHAR, self.onNameChanged),
  38              (self.referrerComboBox, wx.EVT_COMBOBOX, self.onReferrerEntered),
  39              (self.referrerComboBox, wx.EVT_TEXT, self.onReferrerEntered),
  40              (self.insuranceCheckBox, wx.EVT_CHECKBOX, self.onInsuranceChanged),
  41              (self.colorRadioBox, wx.EVT_RADIOBOX, self.onColorchanged)]:
  42             control.Bind(event, handler)
  43 
  44     def doLayout(self):
  45         ''' Layout the controls that were created by createControls(). 
  46             Form.doLayout() will raise a NotImplementedError because it 
  47             is the responsibility of subclasses to layout the controls. '''
  48         raise NotImplementedError
  49 
  50     # Callback methods:
  51 
  52     def onColorchanged(self, event):
  53         self.__log('User wants color: %s'%self.colors[event.GetInt()])
  54 
  55     def onReferrerEntered(self, event):
  56         self.__log('User entered referrer: %s'%event.GetString())
  57 
  58     def onSave(self,event):
  59         self.__log('User clicked on button with id %d'%event.GetId())
  60 
  61     def onNameEntered(self, event):
  62         self.__log('User entered name: %s'%event.GetString())
  63 
  64     def onNameChanged(self, event):
  65         self.__log('User typed character: %d'%event.GetKeyCode())
  66         event.Skip()
  67 
  68     def onInsuranceChanged(self, event):
  69         self.__log('User wants insurance: %s'%bool(event.Checked()))
  70 
  71     # Helper method(s):
  72 
  73     def __log(self, message):
  74         ''' Private method to append a string to the logger text
  75             control. '''
  76         self.logger.AppendText('%s\n'%message)
  77 
  78 
  79 class FormWithAbsolutePositioning(Form):
  80     def doLayout(self):
  81         ''' Layout the controls by means of absolute positioning. '''
  82         for control, x, y, width, height in \
                [(self.logger, 300, 20, 200, 300),
  83                  (self.nameLabel, 20, 60, -1, -1),
  84                  (self.nameTextCtrl, 150, 60, 150, -1),
  85                  (self.referrerLabel, 20, 90, -1, -1),
  86                  (self.referrerComboBox, 150, 90, 95, -1),
  87                  (self.insuranceCheckBox, 20, 180, -1, -1),
  88                  (self.colorRadioBox, 20, 210, -1, -1),
  89                  (self.saveButton, 200, 300, -1, -1)]:
  90             control.SetDimensions(x=x, y=y, width=width, height=height)
  91 
  92 
  93 class FormWithSizer(Form):
  94     def doLayout(self):
  95         ''' Layout the controls by means of sizers. '''
  96 
  97         # A horizontal BoxSizer will contain the GridSizer (on the left)
  98         # and the logger text control (on the right):
  99         boxSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
 100         # A GridSizer will contain the other controls:
 101         gridSizer = wx.FlexGridSizer(rows=5, cols=2, vgap=10, hgap=10)
 102 
 103         # Prepare some reusable arguments for calling sizer.Add():
 104         expandOption = dict(flag=wx.EXPAND)
 105         noOptions = dict()
 106         emptySpace = ((0, 0), noOptions)
 107 
 108         # Add the controls to the sizers:
 109         for control, options in \
                [(self.nameLabel, noOptions),
 110                  (self.nameTextCtrl, expandOption),
 111                  (self.referrerLabel, noOptions),
 112                  (self.referrerComboBox, expandOption),
 113                   emptySpace,
 114                  (self.insuranceCheckBox, noOptions),
 115                   emptySpace,
 116                  (self.colorRadioBox, noOptions),
 117                   emptySpace,
 118                  (self.saveButton, dict(flag=wx.ALIGN_CENTER))]:
 119             gridSizer.Add(control, **options)
 120 
 121         for control, options in \
                [(gridSizer, dict(border=5, flag=wx.ALL)),
 122                  (self.logger, dict(border=5, flag=wx.ALL|wx.EXPAND,
 123                     proportion=1))]:
 124             boxSizer.Add(control, **options)
 125 
 126         self.SetSizerAndFit(boxSizer)
 127 
 128 
 129 class FrameWithForms(wx.Frame):
 130     def __init__(self, *args, **kwargs):
 131         super(FrameWithForms, self).__init__(*args, **kwargs)
 132         notebook = wx.Notebook(self)
 133         form1 = FormWithAbsolutePositioning(notebook)
 134         form2 = FormWithSizer(notebook)
 135         notebook.AddPage(form1, 'Absolute Positioning')
 136         notebook.AddPage(form2, 'Sizers')
 137         # We just set the frame to the right size manually. This is feasible
 138         # for the frame since the frame contains just one component. If the
 139         # frame had contained more than one component, we would use sizers
 140         # of course, as demonstrated in the FormWithSizer class above.
 141         self.SetClientSize(notebook.GetBestSize())
 142 
 143 
 144 if __name__ == '__main__':
 145     app = wx.App(0)
 146     frame = FrameWithForms(None, title='Demo with Notebook')
 147     frame.Show()
 148     app.MainLoop()

WxHowtoBuildingForms (last edited 2008-03-11 10:50:32 by localhost)