]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/MaskedNumCtrl.py
7 from wx
.lib
import masked
9 #----------------------------------------------------------------------
11 class TestPanel( wx
.Panel
):
12 def __init__( self
, parent
, log
):
14 wx
.Panel
.__init
__( self
, parent
, -1 )
16 panel
= wx
.Panel( self
, -1 )
18 header
= wx
.StaticText(panel
, -1, """\
19 This shows the various options for masked.NumCtrl.
20 The controls at the top reconfigure the resulting control at the bottom.
22 header
.SetForegroundColour( "Blue" )
24 intlabel
= wx
.StaticText( panel
, -1, "Integer width:" )
25 self
.integerwidth
= masked
.NumCtrl(
26 panel
, value
=10, integerWidth
=2, allowNegative
=False
29 fraclabel
= wx
.StaticText( panel
, -1, "Fraction width:" )
30 self
.fractionwidth
= masked
.NumCtrl(
31 panel
, value
=0, integerWidth
=2, allowNegative
=False
34 groupcharlabel
= wx
.StaticText( panel
,-1, "Grouping char:" )
35 self
.groupchar
= masked
.TextCtrl(
36 panel
, -1, value
=',', mask
='*', includeChars
= ' ', excludeChars
= '-()0123456789',
37 formatcodes
='F', emptyInvalid
=False, validRequired
=True
40 decimalcharlabel
= wx
.StaticText( panel
,-1, "Decimal char:" )
41 self
.decimalchar
= masked
.TextCtrl(
42 panel
, -1, value
='.', mask
='&', excludeChars
= '-()',
43 formatcodes
='F', emptyInvalid
=True, validRequired
=True
46 self
.set_min
= wx
.CheckBox( panel
, -1, "Set minimum value:" )
47 # Create this masked.NumCtrl using factory, to show how:
48 self
.min = masked
.Ctrl( panel
, integerWidth
=5, fractionWidth
=2, controlType
=masked
.controlTypes
.NUMBER
)
49 self
.min.Enable( False )
51 self
.set_max
= wx
.CheckBox( panel
, -1, "Set maximum value:" )
52 self
.max = masked
.NumCtrl( panel
, integerWidth
=5, fractionWidth
=2 )
53 self
.max.Enable( False )
56 self
.limit_target
= wx
.CheckBox( panel
, -1, "Limit control" )
57 self
.limit_on_field_change
= wx
.CheckBox( panel
, -1, "Limit on field change" )
58 self
.allow_none
= wx
.CheckBox( panel
, -1, "Allow empty control" )
59 self
.group_digits
= wx
.CheckBox( panel
, -1, "Group digits" )
60 self
.group_digits
.SetValue( True )
61 self
.allow_negative
= wx
.CheckBox( panel
, -1, "Allow negative values" )
62 self
.allow_negative
.SetValue( True )
63 self
.use_parens
= wx
.CheckBox( panel
, -1, "Use parentheses" )
64 self
.select_on_entry
= wx
.CheckBox( panel
, -1, "Select on entry" )
65 self
.select_on_entry
.SetValue( True )
67 label
= wx
.StaticText( panel
, -1, "Resulting numeric control:" )
68 font
= label
.GetFont()
69 font
.SetWeight(wx
.BOLD
)
72 self
.target_ctl
= masked
.NumCtrl( panel
, -1, name
="target control" )
74 label_numselect
= wx
.StaticText( panel
, -1, """\
75 Programmatically set the above
77 self
.numselect
= wx
.ComboBox(panel
, -1, choices
= [ '0', '111', '222.22', '-3', '54321.666666666', '-1353.978',
78 '1234567', '-1234567', '123456789', '-123456789.1',
79 '1234567890.', '-9876543210.9' ])
81 grid1
= wx
.FlexGridSizer( 0, 4, 0, 0 )
82 grid1
.Add( intlabel
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5)
83 grid1
.Add( self
.integerwidth
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
85 grid1
.Add( groupcharlabel
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5)
86 grid1
.Add( self
.groupchar
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
88 grid1
.Add( fraclabel
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5 )
89 grid1
.Add( self
.fractionwidth
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
91 grid1
.Add( decimalcharlabel
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5)
92 grid1
.Add( self
.decimalchar
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
94 grid1
.Add( self
.set_min
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5 )
95 grid1
.Add( self
.min, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
96 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
97 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
99 grid1
.Add( self
.set_max
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5 )
100 grid1
.Add( self
.max, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
101 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
102 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
105 grid1
.Add( self
.limit_target
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
106 grid1
.Add( self
.limit_on_field_change
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
108 hbox1
= wx
.BoxSizer( wx
.HORIZONTAL
)
109 hbox1
.Add( (17,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
110 hbox1
.Add( self
.allow_none
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
111 grid1
.Add( hbox1
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
112 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
114 grid1
.Add( self
.group_digits
, 0, wx
.ALIGN_LEFT|wx
.LEFT
, 5 )
115 grid1
.Add( self
.allow_negative
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
116 hbox2
= wx
.BoxSizer( wx
.HORIZONTAL
)
117 hbox2
.Add( (17,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
118 hbox2
.Add( self
.use_parens
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
119 grid1
.Add( hbox2
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
120 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
122 grid1
.Add( self
.select_on_entry
, 0, wx
.ALIGN_LEFT|wx
.LEFT
, 5 )
123 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
124 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
125 grid1
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
127 grid2
= wx
.FlexGridSizer( 0, 2, 0, 0 )
128 grid2
.Add( label
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5 )
129 grid2
.Add( self
.target_ctl
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
130 grid2
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
131 grid2
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
132 grid2
.Add( label_numselect
, 0, wx
.ALIGN_LEFT|wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, 5 )
133 grid2
.Add( self
.numselect
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 5 )
134 grid2
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
135 grid2
.Add( (5,5), 0, wx
.ALIGN_LEFT|wx
.ALL
, 5)
136 grid2
.AddGrowableCol(1)
138 self
.outer_box
= wx
.BoxSizer( wx
.VERTICAL
)
139 self
.outer_box
.Add(header
, 0, wx
.ALIGN_LEFT|wx
.TOP|wx
.LEFT
, 20)
140 self
.outer_box
.Add( grid1
, 0, wx
.ALIGN_CENTRE|wx
.LEFT|wx
.BOTTOM|wx
.RIGHT
, 20 )
141 self
.outer_box
.Add( grid2
, 0, wx
.ALIGN_LEFT|wx
.ALL
, 20 )
144 panel
.SetAutoLayout( True )
145 panel
.SetSizer( self
.outer_box
)
146 self
.outer_box
.Fit( panel
)
147 panel
.Move( (50,10) )
150 self
.Bind(masked
.EVT_NUM
, self
.OnSetIntWidth
, self
.integerwidth
)
151 self
.Bind(masked
.EVT_NUM
, self
.OnSetFractionWidth
, self
.fractionwidth
)
152 self
.Bind(wx
.EVT_TEXT
, self
.OnSetGroupChar
, self
.groupchar
)
153 self
.Bind(wx
.EVT_TEXT
, self
.OnSetDecimalChar
, self
.decimalchar
)
155 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetMin
, self
.set_min
)
156 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetMax
, self
.set_max
)
157 self
.Bind(masked
.EVT_NUM
, self
.SetTargetMinMax
, self
.min )
158 self
.Bind(masked
.EVT_NUM
, self
.SetTargetMinMax
, self
.max )
160 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetLimited
, self
.limit_target
)
161 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetLimitOnFieldChange
, self
.limit_on_field_change
)
162 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetAllowNone
, self
.allow_none
)
163 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetGroupDigits
, self
.group_digits
)
164 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetAllowNegative
, self
.allow_negative
)
165 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetUseParens
, self
.use_parens
)
166 self
.Bind(wx
.EVT_CHECKBOX
, self
.OnSetSelectOnEntry
, self
.select_on_entry
)
168 self
.Bind(masked
.EVT_NUM
, self
.OnTargetChange
, self
.target_ctl
)
169 self
.Bind(wx
.EVT_COMBOBOX
, self
.OnNumberSelect
, self
.numselect
)
172 def OnSetIntWidth(self
, event
):
173 width
= self
.integerwidth
.GetValue()
176 self
.log
.write("integer width must be positive\n")
177 self
.integerwidth
.SetForegroundColour(wx
.RED
)
179 self
.integerwidth
.SetForegroundColour(wx
.BLACK
)
180 self
.log
.write("setting integer width to %d\n" % width
)
181 self
.target_ctl
.SetParameters( integerWidth
= width
)
182 # Now resize and fit the dialog as appropriate:
183 self
.grid2
.SetItemMinSize(self
.target_ctl
, self
.target_ctl
.GetSize())
184 self
.outer_box
.Fit( self
.panel
)
185 self
.outer_box
.SetSizeHints( self
.panel
)
188 def OnSetFractionWidth(self
, event
):
189 width
= self
.fractionwidth
.GetValue()
190 self
.log
.write("setting fraction width to %d\n" % width
)
191 self
.target_ctl
.SetParameters( fractionWidth
= width
)
192 # Now resize and fit the dialog as appropriate:
193 self
.grid2
.SetItemMinSize(self
.target_ctl
, self
.target_ctl
.GetSize())
194 self
.outer_box
.Fit( self
.panel
)
195 self
.outer_box
.SetSizeHints( self
.panel
)
198 def OnSetGroupChar( self
, event
):
199 char
= self
.groupchar
.GetValue()
200 if self
.target_ctl
.GetDecimalChar() == char
:
201 self
.log
.write("group and decimal chars must be different\n")
202 self
.groupchar
.SetForegroundColour(wx
.RED
)
204 self
.groupchar
.SetForegroundColour(wx
.BLACK
)
205 self
.log
.write("setting group char to %s\n" % char
)
206 self
.target_ctl
.SetGroupChar( char
)
208 def OnSetDecimalChar( self
, event
):
209 char
= self
.decimalchar
.GetValue()
210 if self
.target_ctl
.GetGroupChar() == char
:
211 self
.log
.write("group and decimal chars must be different\n")
212 self
.decimalchar
.SetForegroundColour(wx
.RED
)
214 self
.decimalchar
.SetForegroundColour(wx
.BLACK
)
215 self
.log
.write("setting decimal char to %s\n" % char
)
216 self
.target_ctl
.SetDecimalChar( char
)
219 def OnSetMin( self
, event
):
220 self
.min.Enable( self
.set_min
.GetValue() )
221 self
.SetTargetMinMax()
223 def OnSetMax( self
, event
):
224 self
.max.Enable( self
.set_max
.GetValue() )
225 self
.SetTargetMinMax()
228 def OnSetLimited( self
, event
):
229 limited
= self
.limit_target
.GetValue()
230 self
.target_ctl
.SetLimited( limited
)
231 limit_on_field_change
= self
.limit_on_field_change
.GetValue()
232 if limited
and limit_on_field_change
:
233 self
.limit_on_field_change
.SetValue(False)
234 self
.target_ctl
.SetLimitOnFieldChange( False )
235 self
.SetTargetMinMax()
238 def OnSetLimitOnFieldChange( self
, event
):
239 limit_on_field_change
= self
.limit_on_field_change
.GetValue()
240 self
.target_ctl
.SetLimitOnFieldChange( limit_on_field_change
)
241 limited
= self
.limit_target
.GetValue()
242 if limited
and limit_on_field_change
:
243 self
.limit_target
.SetValue(False)
244 self
.target_ctl
.SetLimited( False )
246 def SetTargetMinMax( self
, event
=None ):
248 if self
.set_min
.GetValue():
249 min = self
.min.GetValue()
250 if self
.set_max
.GetValue():
251 max = self
.max.GetValue()
253 cur_min
, cur_max
= self
.target_ctl
.GetBounds()
255 if min != cur_min
and not self
.target_ctl
.SetMin( min ):
256 if self
.target_ctl
.GetMax() is None and cur_max
> min:
257 self
.log
.write( "min (%d) won't fit in control -- bound not set\n" % min )
259 self
.log
.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self
.target_ctl
.GetMax() ) )
260 self
.min.SetParameters( signedForegroundColour
=wx
.RED
, foregroundColour
=wx
.RED
)
262 self
.min.SetParameters( signedForegroundColour
=wx
.BLACK
, foregroundColour
=wx
.BLACK
)
265 if max != cur_max
and not self
.target_ctl
.SetMax( max ):
266 if self
.target_ctl
.GetMax() is None and cur_min
< max:
267 self
.log
.write( "max (%d) won't fit in control -- bound not set\n" % max )
269 self
.log
.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self
.target_ctl
.GetMin() ) )
270 self
.max.SetParameters( signedForegroundColour
=wx
.RED
, foregroundColour
=wx
.RED
)
272 self
.max.SetParameters( signedForegroundColour
=wx
.BLACK
, foregroundColour
=wx
.BLACK
)
275 if min != cur_min
or max != cur_max
:
276 new_min
, new_max
= self
.target_ctl
.GetBounds()
277 self
.log
.write( "current min, max: (%s, %s)\n" % ( str(new_min
), str(new_max
) ) )
280 def OnSetAllowNone( self
, event
):
281 self
.target_ctl
.SetAllowNone( self
.allow_none
.GetValue() )
284 def OnSetGroupDigits( self
, event
):
285 self
.target_ctl
.SetGroupDigits( self
.group_digits
.GetValue() )
286 # Now resize and fit the dialog as appropriate:
287 self
.grid2
.SetItemMinSize(self
.target_ctl
, self
.target_ctl
.GetSize())
288 self
.outer_box
.Fit( self
.panel
)
289 self
.outer_box
.SetSizeHints( self
.panel
)
292 def OnSetAllowNegative( self
, event
):
293 if self
.allow_negative
.GetValue():
294 self
.use_parens
.Enable(True)
295 self
.target_ctl
.SetParameters(allowNegative
=True,
296 useParensForNegatives
= self
.use_parens
.GetValue())
298 self
.target_ctl
.SetAllowNegative(False)
299 # Now resize and fit the dialog as appropriate:
300 self
.grid2
.SetItemMinSize(self
.target_ctl
, self
.target_ctl
.GetSize())
301 self
.outer_box
.Fit( self
.panel
)
302 self
.outer_box
.SetSizeHints( self
.panel
)
305 def OnSetUseParens( self
, event
):
306 self
.target_ctl
.SetUseParensForNegatives( self
.use_parens
.GetValue() )
307 # Now resize and fit the dialog as appropriate:
308 self
.grid2
.SetItemMinSize(self
.target_ctl
, self
.target_ctl
.GetSize())
309 self
.outer_box
.Fit( self
.panel
)
310 self
.outer_box
.SetSizeHints( self
.panel
)
313 def OnSetSelectOnEntry( self
, event
):
314 self
.target_ctl
.SetSelectOnEntry( self
.select_on_entry
.GetValue() )
317 def OnTargetChange( self
, event
):
318 ctl
= event
.GetEventObject()
319 value
= ctl
.GetValue()
320 ib_str
= [ " (out of bounds)", "" ]
321 self
.log
.write( "value = %s (%s)%s\n" % ( repr(value
), repr(type(value
)), ib_str
[ ctl
.IsInBounds(value
) ] ) )
324 def OnNumberSelect( self
, event
):
325 value
= event
.GetString()
327 if value
.find('.') != -1:
328 numvalue
= float(value
)
330 numvalue
= long(value
)
332 numvalue
= value
# try to clear the value again
335 self
.target_ctl
.SetValue(numvalue
)
337 type, value
, tb
= sys
.exc_info()
338 for line
in traceback
.format_exception_only(type, value
):
342 #----------------------------------------------------------------------
344 def runTest( frame
, nb
, log
):
345 win
= TestPanel( nb
, log
)
348 #----------------------------------------------------------------------
349 import wx
.lib
.masked
.numctrl
as mnum
352 """ + mnum
.__doc
__ + """
355 if __name__
== '__main__':
358 run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])