| 1 | |
| 2 | import string |
| 3 | import wx |
| 4 | |
| 5 | #---------------------------------------------------------------------- |
| 6 | |
| 7 | ALPHA_ONLY = 1 |
| 8 | DIGIT_ONLY = 2 |
| 9 | |
| 10 | class MyValidator(wx.PyValidator): |
| 11 | def __init__(self, flag=None, pyVar=None): |
| 12 | wx.PyValidator.__init__(self) |
| 13 | self.flag = flag |
| 14 | self.Bind(wx.EVT_CHAR, self.OnChar) |
| 15 | |
| 16 | def Clone(self): |
| 17 | return MyValidator(self.flag) |
| 18 | |
| 19 | def Validate(self, win): |
| 20 | tc = self.GetWindow() |
| 21 | val = tc.GetValue() |
| 22 | |
| 23 | if self.flag == ALPHA_ONLY: |
| 24 | for x in val: |
| 25 | if x not in string.letters: |
| 26 | return False |
| 27 | |
| 28 | elif self.flag == DIGIT_ONLY: |
| 29 | for x in val: |
| 30 | if x not in string.digits: |
| 31 | return False |
| 32 | |
| 33 | return True |
| 34 | |
| 35 | |
| 36 | def OnChar(self, event): |
| 37 | key = event.KeyCode() |
| 38 | |
| 39 | if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: |
| 40 | event.Skip() |
| 41 | return |
| 42 | |
| 43 | if self.flag == ALPHA_ONLY and chr(key) in string.letters: |
| 44 | event.Skip() |
| 45 | return |
| 46 | |
| 47 | if self.flag == DIGIT_ONLY and chr(key) in string.digits: |
| 48 | event.Skip() |
| 49 | return |
| 50 | |
| 51 | if not wx.Validator_IsSilent(): |
| 52 | wx.Bell() |
| 53 | |
| 54 | # Returning without calling even.Skip eats the event before it |
| 55 | # gets to the text control |
| 56 | return |
| 57 | |
| 58 | #---------------------------------------------------------------------- |
| 59 | |
| 60 | class TestValidatorPanel(wx.Panel): |
| 61 | def __init__(self, parent): |
| 62 | wx.Panel.__init__(self, parent, -1) |
| 63 | self.SetAutoLayout(True) |
| 64 | VSPACE = 10 |
| 65 | |
| 66 | fgs = wx.FlexGridSizer(0, 2) |
| 67 | |
| 68 | fgs.Add((1,1)) |
| 69 | fgs.Add(wx.StaticText(self, -1, "These controls have validators that limit\n" |
| 70 | "the type of characters that can be entered.")) |
| 71 | |
| 72 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 73 | |
| 74 | label = wx.StaticText(self, -1, "Alpha Only: ") |
| 75 | fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) |
| 76 | |
| 77 | fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(ALPHA_ONLY))) |
| 78 | |
| 79 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 80 | |
| 81 | label = wx.StaticText(self, -1, "Digits Only: ") |
| 82 | fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) |
| 83 | fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(DIGIT_ONLY))) |
| 84 | |
| 85 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 86 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 87 | fgs.Add((0,0)) |
| 88 | b = wx.Button(self, -1, "Test Dialog Validation") |
| 89 | self.Bind(wx.EVT_BUTTON, self.OnDoDialog, b) |
| 90 | fgs.Add(b) |
| 91 | |
| 92 | border = wx.BoxSizer() |
| 93 | border.Add(fgs, 1, wx.GROW|wx.ALL, 25) |
| 94 | self.SetSizer(border) |
| 95 | self.Layout() |
| 96 | |
| 97 | def OnDoDialog(self, evt): |
| 98 | dlg = TestValidateDialog(self) |
| 99 | dlg.ShowModal() |
| 100 | dlg.Destroy() |
| 101 | |
| 102 | |
| 103 | #---------------------------------------------------------------------- |
| 104 | |
| 105 | class TextObjectValidator(wx.PyValidator): |
| 106 | """ This validator is used to ensure that the user has entered something |
| 107 | into the text object editor dialog's text field. |
| 108 | """ |
| 109 | def __init__(self): |
| 110 | """ Standard constructor. |
| 111 | """ |
| 112 | wx.PyValidator.__init__(self) |
| 113 | |
| 114 | |
| 115 | |
| 116 | def Clone(self): |
| 117 | """ Standard cloner. |
| 118 | |
| 119 | Note that every validator must implement the Clone() method. |
| 120 | """ |
| 121 | return TextObjectValidator() |
| 122 | |
| 123 | |
| 124 | def Validate(self, win): |
| 125 | """ Validate the contents of the given text control. |
| 126 | """ |
| 127 | textCtrl = self.GetWindow() |
| 128 | text = textCtrl.GetValue() |
| 129 | |
| 130 | if len(text) == 0: |
| 131 | wx.MessageBox("A text object must contain some text!", "Error") |
| 132 | textCtrl.SetBackgroundColour("pink") |
| 133 | textCtrl.SetFocus() |
| 134 | textCtrl.Refresh() |
| 135 | return False |
| 136 | else: |
| 137 | textCtrl.SetBackgroundColour( |
| 138 | wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) |
| 139 | textCtrl.Refresh() |
| 140 | return True |
| 141 | |
| 142 | |
| 143 | def TransferToWindow(self): |
| 144 | """ Transfer data from validator to window. |
| 145 | |
| 146 | The default implementation returns False, indicating that an error |
| 147 | occurred. We simply return True, as we don't do any data transfer. |
| 148 | """ |
| 149 | return True # Prevent wxDialog from complaining. |
| 150 | |
| 151 | |
| 152 | def TransferFromWindow(self): |
| 153 | """ Transfer data from window to validator. |
| 154 | |
| 155 | The default implementation returns False, indicating that an error |
| 156 | occurred. We simply return True, as we don't do any data transfer. |
| 157 | """ |
| 158 | return True # Prevent wxDialog from complaining. |
| 159 | |
| 160 | #---------------------------------------------------------------------- |
| 161 | |
| 162 | class TestValidateDialog(wx.Dialog): |
| 163 | def __init__(self, parent): |
| 164 | wx.Dialog.__init__(self, parent, -1, "Validated Dialog") |
| 165 | |
| 166 | self.SetAutoLayout(True) |
| 167 | VSPACE = 10 |
| 168 | |
| 169 | fgs = wx.FlexGridSizer(0, 2) |
| 170 | |
| 171 | fgs.Add((1,1)); |
| 172 | fgs.Add(wx.StaticText(self, -1, |
| 173 | "These controls must have text entered into them. Each\n" |
| 174 | "one has a validator that is checked when the Okay\n" |
| 175 | "button is clicked.")) |
| 176 | |
| 177 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 178 | |
| 179 | label = wx.StaticText(self, -1, "First: ") |
| 180 | fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) |
| 181 | |
| 182 | fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator())) |
| 183 | |
| 184 | fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) |
| 185 | |
| 186 | label = wx.StaticText(self, -1, "Second: ") |
| 187 | fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) |
| 188 | fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator())) |
| 189 | |
| 190 | |
| 191 | buttons = wx.BoxSizer(wx.HORIZONTAL) |
| 192 | b = wx.Button(self, wx.ID_OK, "Okay") |
| 193 | b.SetDefault() |
| 194 | buttons.Add(b, 0, wx.ALL, 10) |
| 195 | buttons.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 0, wx.ALL, 10) |
| 196 | |
| 197 | border = wx.BoxSizer(wx.VERTICAL) |
| 198 | border.Add(fgs, 1, wx.GROW|wx.ALL, 25) |
| 199 | border.Add(buttons) |
| 200 | self.SetSizer(border) |
| 201 | border.Fit(self) |
| 202 | self.Layout() |
| 203 | |
| 204 | |
| 205 | #---------------------------------------------------------------------- |
| 206 | |
| 207 | def runTest(frame, nb, log): |
| 208 | win = TestValidatorPanel(nb) |
| 209 | return win |
| 210 | |
| 211 | #---------------------------------------------------------------------- |
| 212 | |
| 213 | |
| 214 | |
| 215 | overview = """\ |
| 216 | <html> |
| 217 | <body> |
| 218 | wx.Validator is the base class for a family of validator classes that mediate |
| 219 | between a class of control, and application data. |
| 220 | |
| 221 | <p>A validator has three major roles: |
| 222 | |
| 223 | <p><ol> |
| 224 | <li>to transfer data from a C++ variable or own storage to and from a control; |
| 225 | <li>to validate data in a control, and show an appropriate error message; |
| 226 | <li>to filter events (such as keystrokes), thereby changing the behaviour of the associated control. |
| 227 | </ol> |
| 228 | <p>Validators can be plugged into controls dynamically. |
| 229 | </body> |
| 230 | </html> |
| 231 | """ |
| 232 | |
| 233 | |
| 234 | |
| 235 | if __name__ == '__main__': |
| 236 | import sys,os |
| 237 | import run |
| 238 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) |
| 239 | |