Introduction
This part of the series exhibits a validator that uses these state machines as plug-ins. The code is adapted from what is offered in the wxPython demo.
Process Overview
Import the module that contains SMValidator and instantiate it with a suitable version of the state machine. In the following example the state machines for North American telephone numbers and Canadian postal codes are used.
The Validate and OnChar methods of the validator use the convenience functions to determine whether the entire user input or the most recent character respectively should be accepted.
It might be worth mentioning that these state machines are capable of accumulating tokens. For example, when a user enters the telephone number "9055451111" the state machine makes this available as "(905) 545-1111," which might be a convenient form in which to persist it. (See part IV for details about accummulating tokens.)
Special Concerns
- The validator does not attempt to deal properly with backspace and (horizontal) arrow characters.
I do not understand how to use TransferFromWindow and TransferToWindow properly in wxPython. Perhaps someone could add to this recipe, or provide a separate one?
Code Sample
1 from wxPython.wx import *
2
3 class SMValidator ( wxPyValidator ) :
4
5 def __init__ ( self, statemachine ) :
6
7 wxPyValidator . __init__ ( self )
8 self . statemachine = statemachine
9 EVT_CHAR ( self, self . OnChar )
10
11 def Clone ( self ) :
12
13 return self . __class__ ( self . statemachine )
14
15 def Validate ( self, win ) :
16
17 val = self . GetWindow ( ) . GetValue ( )
18 if not val : return True
19 result = self . statemachine . testString ( val )
20 return result . validatedString ( )
21
22 def OnChar ( self, event ) :
23
24 keyCode = event . KeyCode ( )
25 if keyCode < WXK_SPACE or keyCode == WXK_DELETE or keyCode > 255:
26 event . Skip ( )
27 return
28 key = chr ( keyCode )
29 val = self . GetWindow ( ) . GetValue ( )
30 result = self . statemachine . testString ( val + key )
31 if result . rejectCharacter ( ) : return
32 event . Skip ( )
33
34 def TransferFromWindow ( self ) : return True
35
36 def TransferToWindow ( self ) : return True
37
38 if __name__ == "__main__" :
39
40 from phoneNumberSM import statemachine as phoneNumberSM
41 from postalCodeSM import statemachine as postalCodeSM
42
43 class TrialDialog ( wxDialog ) :
44
45 def __init__ ( self, parent ) :
46
47 wxDialog . __init__ ( self, parent, -1, '', size = wxSize ( 400, 200 ) )
48
49 wxButton ( self, wxID_OK, '&OK', pos = wxPoint ( 200, 130 ) )
50
51 wxStaticText ( self, -1, 'Telephone', pos = wxPoint ( 100, 50 ) )
52 textctrl = wxTextCtrl ( self, -1, '', pos = wxPoint ( 200, 50 ),
53 validator = SMValidator ( phoneNumberSM ) )
54
55 wxStaticText ( self, -1, 'Postal code', pos = wxPoint ( 100, 80 ) )
56 textctrl = wxTextCtrl ( self, -1, '', pos = wxPoint ( 200, 80 ),
57 validator = SMValidator ( postalCodeSM ) )
58
59 app = wxPySimpleApp ( )
60
61 dlg = TrialDialog ( None )
62 dlg . ShowModal ( )
63
64 print phoneNumberSM . allTokens
65 print postalCodeSM . allTokens
66
67 dlg . Destroy ( )
68
69 app . MainLoop ( )
Comments
I welcome your comments. - Bill Bell