📄 numctrl.py
字号:
SetAllowNone(bool)
If called with a value of True, this function will cause the control
to allow the value to be empty, representing a value of None.
If called with a value of False, this function will prevent the value
from being None. If the value of the control is currently None,
ie. the control is empty, then the value will be changed to that
of the lower bound of the control, or 0 if no lower bound is set.
GetAllowNone()
IsNoneAllowed()
Returns <I>True</I> if the control currently allows its
value to be None.
SetAllowNegative(bool)
If called with a value of True, this function will cause the
control to allow the value to be negative (and reserve space for
displaying the sign. If called with a value of False, and the
value of the control is currently negative, the value of the
control will be converted to the absolute value, and then
limited appropriately based on the existing bounds of the control
(if any).
GetAllowNegative()
IsNegativeAllowed()
Returns <I>True</I> if the control currently permits values
to be negative.
SetGroupDigits(bool)
If called with a value of True, this will make the control
automatically add and manage grouping characters to the presented
value in integer portion of the control.
GetGroupDigits()
IsGroupingAllowed()
Returns <I>True</I> if the control is currently set to group digits.
SetGroupChar()
Sets the grouping character for the integer portion of the
control. (The default grouping character this is ','.
GetGroupChar()
Returns the current grouping character for the control.
SetSelectOnEntry()
If called with a value of <I>True</I>, this will make the control
automatically select the contents of each field as it is entered
within the control. (The default is True.)
GetSelectOnEntry()
Returns <I>True</I> if the control currently auto selects
the field values on entry.
SetAutoSize(bool)
Resets the autoSize attribute of the control.
GetAutoSize()
Returns the current state of the autoSize attribute for the control.
"""
import copy
import string
import types
import wx
from sys import maxint
MAXINT = maxint # (constants should be in upper case)
MININT = -maxint-1
from wx.tools.dbg import Logger
from wx.lib.masked import MaskedEditMixin, Field, BaseMaskedTextCtrl
dbg = Logger()
##dbg(enable=1)
#----------------------------------------------------------------------------
wxEVT_COMMAND_MASKED_NUMBER_UPDATED = wx.NewEventType()
EVT_NUM = wx.PyEventBinder(wxEVT_COMMAND_MASKED_NUMBER_UPDATED, 1)
#----------------------------------------------------------------------------
class NumberUpdatedEvent(wx.PyCommandEvent):
"""
Used to fire an EVT_NUM event whenever the value in a NumCtrl changes.
"""
def __init__(self, id, value = 0, object=None):
wx.PyCommandEvent.__init__(self, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, id)
self.__value = value
self.SetEventObject(object)
def GetValue(self):
"""Retrieve the value of the control at the time
this event was generated."""
return self.__value
#----------------------------------------------------------------------------
class NumCtrlAccessorsMixin:
"""
Defines masked.NumCtrl's list of attributes having their own
Get/Set functions, ignoring those that make no sense for
a numeric control.
"""
exposed_basectrl_params = (
'decimalChar',
'shiftDecimalChar',
'groupChar',
'useParensForNegatives',
'defaultValue',
'description',
'useFixedWidthFont',
'autoSize',
'signedForegroundColour',
'emptyBackgroundColour',
'validBackgroundColour',
'invalidBackgroundColour',
'emptyInvalid',
'validFunc',
'validRequired',
)
for param in exposed_basectrl_params:
propname = param[0].upper() + param[1:]
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
if param.find('Colour') != -1:
# add non-british spellings, for backward-compatibility
propname.replace('Colour', 'Color')
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
#----------------------------------------------------------------------------
class NumCtrl(BaseMaskedTextCtrl, NumCtrlAccessorsMixin):
"""
Masked edit control supporting "native" numeric values, ie. .SetValue(3), for
example, and supporting a variety of formatting options, including automatic
rounding specifiable precision, grouping and decimal place characters, etc.
"""
valid_ctrl_params = {
'integerWidth': 10, # by default allow all 32-bit integers
'fractionWidth': 0, # by default, use integers
'decimalChar': '.', # by default, use '.' for decimal point
'allowNegative': True, # by default, allow negative numbers
'useParensForNegatives': False, # by default, use '-' to indicate negatives
'groupDigits': True, # by default, don't insert grouping
'groupChar': ',', # by default, use ',' for grouping
'min': None, # by default, no bounds set
'max': None,
'limited': False, # by default, no limiting even if bounds set
'allowNone': False, # by default, don't allow empty value
'selectOnEntry': True, # by default, select the value of each field on entry
'foregroundColour': "Black",
'signedForegroundColour': "Red",
'emptyBackgroundColour': "White",
'validBackgroundColour': "White",
'invalidBackgroundColour': "Yellow",
'useFixedWidthFont': True, # by default, use a fixed-width font
'autoSize': True, # by default, set the width of the control based on the mask
}
def __init__ (
self, parent, id=-1, value = 0,
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = wx.TE_PROCESS_TAB, validator = wx.DefaultValidator,
name = "masked.num",
**kwargs ):
## dbg('masked.NumCtrl::__init__', indent=1)
# Set defaults for control:
## dbg('setting defaults:')
for key, param_value in NumCtrl.valid_ctrl_params.items():
# This is done this way to make setattr behave consistently with
# "private attribute" name mangling
setattr(self, '_' + key, copy.copy(param_value))
# Assign defaults for all attributes:
init_args = copy.deepcopy(NumCtrl.valid_ctrl_params)
## dbg('kwargs:', kwargs)
for key, param_value in kwargs.items():
key = key.replace('Color', 'Colour')
if key not in NumCtrl.valid_ctrl_params.keys():
raise AttributeError('invalid keyword argument "%s"' % key)
else:
init_args[key] = param_value
## dbg('init_args:', indent=1)
for key, param_value in init_args.items():
## dbg('%s:' % key, param_value)
pass
## dbg(indent=0)
# Process initial fields for the control, as part of construction:
if type(init_args['integerWidth']) != types.IntType:
raise AttributeError('invalid integerWidth (%s) specified; expected integer' % repr(init_args['integerWidth']))
elif init_args['integerWidth'] < 1:
raise AttributeError('invalid integerWidth (%s) specified; must be > 0' % repr(init_args['integerWidth']))
fields = {}
if init_args.has_key('fractionWidth'):
if type(init_args['fractionWidth']) != types.IntType:
raise AttributeError('invalid fractionWidth (%s) specified; expected integer' % repr(self._fractionWidth))
elif init_args['fractionWidth'] < 0:
raise AttributeError('invalid fractionWidth (%s) specified; must be >= 0' % repr(init_args['fractionWidth']))
self._fractionWidth = init_args['fractionWidth']
if self._fractionWidth:
fracmask = '.' + '#{%d}' % self._fractionWidth
## dbg('fracmask:', fracmask)
fields[1] = Field(defaultValue='0'*self._fractionWidth)
else:
fracmask = ''
self._integerWidth = init_args['integerWidth']
if init_args['groupDigits']:
self._groupSpace = (self._integerWidth - 1) / 3
else:
self._groupSpace = 0
intmask = '#{%d}' % (self._integerWidth + self._groupSpace)
if self._fractionWidth:
emptyInvalid = False
else:
emptyInvalid = True
fields[0] = Field(formatcodes='r<>', emptyInvalid=emptyInvalid)
## dbg('intmask:', intmask)
# don't bother to reprocess these arguments:
del init_args['integerWidth']
del init_args['fractionWidth']
self._autoSize = init_args['autoSize']
if self._autoSize:
formatcodes = 'FR<'
else:
formatcodes = 'R<'
mask = intmask+fracmask
# initial value of state vars
self._oldvalue = 0
self._integerEnd = 0
self._typedSign = False
# Construct the base control:
BaseMaskedTextCtrl.__init__(
self, parent, id, '',
pos, size, style, validator, name,
mask = mask,
formatcodes = formatcodes,
fields = fields,
validFunc=self.IsInBounds,
setupEventHandling = False)
self.Bind(wx.EVT_SET_FOCUS, self._OnFocus ) ## defeat automatic full selection
self.Bind(wx.EVT_KILL_FOCUS, self._OnKillFocus ) ## run internal validator
self.Bind(wx.EVT_LEFT_DCLICK, self._OnDoubleClick) ## select field under cursor on dclick
self.Bind(wx.EVT_RIGHT_UP, self._OnContextMenu ) ## bring up an appropriate context menu
self.Bind(wx.EVT_KEY_DOWN, self._OnKeyDown ) ## capture control events not normally seen, eg ctrl-tab.
self.Bind(wx.EVT_CHAR, self._OnChar ) ## handle each keypress
self.Bind(wx.EVT_TEXT, self.OnTextChange ) ## color control appropriately & keep
## track of previous value for undo
# Establish any additional parameters, with appropriate error checking
self.SetParameters(**init_args)
# Set the value requested (if possible)
## wxCallAfter(self.SetValue, value)
self.SetValue(value)
# Ensure proper coloring:
self.Refresh()
## dbg('finished NumCtrl::__init__', indent=0)
def SetParameters(self, **kwargs):
"""
This function is used to initialize and reconfigure the control.
See TimeCtrl module overview for available parameters.
"""
## dbg('NumCtrl::SetParameters', indent=1)
maskededit_kwargs = {}
reset_fraction_width = False
if( (kwargs.has_key('integerWidth') and kwargs['integerWidth'] != self._integerWidth)
or (kwargs.has_key('fractionWidth') and kwargs['fractionWidth'] != self._fractionWidth)
or (kwargs.has_key('groupDigits') and kwargs['groupDigits'] != self._groupDigits)
or (kwargs.has_key('autoSize') and kwargs['autoSize'] != self._autoSize) ):
fields = {}
if kwargs.has_key('fractionWidth'):
if type(kwargs['fractionWidth']) != types.IntType:
raise AttributeError('invalid fractionWidth (%s) specified; expected integer' % repr(kwargs['fractionWidth']))
elif kwargs['fractionWidth'] < 0:
raise AttributeError('invalid fractionWidth (%s) specified; must be >= 0' % repr(kwargs['fractionWidth']))
else:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -