📄 maskededit.py
字号:
If not specified as a keyword argument, the default controlType is
controlTypes.TEXT.
"""
"""
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DEVELOPER COMMENTS:
Naming Conventions
------------------
All methods of the Mixin that are not meant to be exposed to the external
interface are prefaced with '_'. Those functions that are primarily
intended to be internal subroutines subsequently start with a lower-case
letter; those that are primarily intended to be used and/or overridden
by derived subclasses start with a capital letter.
The following methods must be used and/or defined when deriving a control
from MaskedEditMixin. NOTE: if deriving from a *masked edit* control
(eg. class IpAddrCtrl(masked.TextCtrl) ), then this is NOT necessary,
as it's already been done for you in the base class.
._SetInitialValue()
This function must be called after the associated base
control has been initialized in the subclass __init__
function. It sets the initial value of the control,
either to the value specified if non-empty, the
default value if specified, or the "template" for
the empty control as necessary. It will also set/reset
the font if necessary and apply formatting to the
control at this time.
._GetSelection()
REQUIRED
Each class derived from MaskedEditMixin must define
the function for getting the start and end of the
current text selection. The reason for this is
that not all controls have the same function name for
doing this; eg. wx.TextCtrl uses .GetSelection(),
whereas we had to write a .GetMark() function for
wxComboBox, because .GetSelection() for the control
gets the currently selected list item from the combo
box, and the control doesn't (yet) natively provide
a means of determining the text selection.
._SetSelection()
REQUIRED
Similarly to _GetSelection, each class derived from
MaskedEditMixin must define the function for setting
the start and end of the current text selection.
(eg. .SetSelection() for masked.TextCtrl, and .SetMark() for
masked.ComboBox.
._GetInsertionPoint()
._SetInsertionPoint()
REQUIRED
For consistency, and because the mixin shouldn't rely
on fixed names for any manipulations it does of any of
the base controls, we require each class derived from
MaskedEditMixin to define these functions as well.
._GetValue()
._SetValue() REQUIRED
Each class derived from MaskedEditMixin must define
the functions used to get and set the raw value of the
control.
This is necessary so that recursion doesn't take place
when setting the value, and so that the mixin can
call the appropriate function after doing all its
validation and manipulation without knowing what kind
of base control it was mixed in with. To handle undo
functionality, the ._SetValue() must record the current
selection prior to setting the value.
.Cut()
.Paste()
.Undo()
.SetValue() REQUIRED
Each class derived from MaskedEditMixin must redefine
these functions to call the _Cut(), _Paste(), _Undo()
and _SetValue() methods, respectively for the control,
so as to prevent programmatic corruption of the control's
value. This must be done in each derivation, as the
mixin cannot itself override a member of a sibling class.
._Refresh() REQUIRED
Each class derived from MaskedEditMixin must define
the function used to refresh the base control.
.Refresh() REQUIRED
Each class derived from MaskedEditMixin must redefine
this function so that it checks the validity of the
control (via self._CheckValid) and then refreshes
control using the base class method.
._IsEditable() REQUIRED
Each class derived from MaskedEditMixin must define
the function used to determine if the base control is
editable or not. (For masked.ComboBox, this has to
be done with code, rather than specifying the proper
function in the base control, as there isn't one...)
._CalcSize() REQUIRED
Each class derived from MaskedEditMixin must define
the function used to determine how wide the control
should be given the mask. (The mixin function
._calcSize() provides a baseline estimate.)
Event Handling
--------------
Event handlers are "chained", and MaskedEditMixin usually
swallows most of the events it sees, thereby preventing any other
handlers from firing in the chain. It is therefore required that
each class derivation using the mixin to have an option to hook up
the event handlers itself or forego this operation and let a
subclass of the masked control do so. For this reason, each
subclass should probably include the following code:
if setupEventHandling:
## Setup event handlers
EVT_SET_FOCUS( self, self._OnFocus ) ## defeat automatic full selection
EVT_KILL_FOCUS( self, self._OnKillFocus ) ## run internal validator
EVT_LEFT_DCLICK(self, self._OnDoubleClick) ## select field under cursor on dclick
EVT_RIGHT_UP(self, self._OnContextMenu ) ## bring up an appropriate context menu
EVT_KEY_DOWN( self, self._OnKeyDown ) ## capture control events not normally seen, eg ctrl-tab.
EVT_CHAR( self, self._OnChar ) ## handle each keypress
EVT_TEXT( self, self.GetId(), self._OnTextChange ) ## color control appropriately & keep
## track of previous value for undo
where setupEventHandling is an argument to its constructor.
These 5 handlers must be "wired up" for the masked edit
controls to provide default behavior. (The setupEventHandling
is an argument to masked.TextCtrl and masked.ComboBox, so
that controls derived from *them* may replace one of these
handlers if they so choose.)
If your derived control wants to preprocess events before
taking action, it should then set up the event handling itself,
so it can be first in the event handler chain.
The following routines are available to facilitate changing
the default behavior of masked edit controls:
._SetKeycodeHandler(keycode, func)
._SetKeyHandler(char, func)
Use to replace default handling for any given keycode.
func should take the key event as argument and return
False if no further action is required to handle the
key. Eg:
self._SetKeycodeHandler(WXK_UP, self.IncrementValue)
self._SetKeyHandler('-', self._OnChangeSign)
(Setting a func of None removes any keyhandler for the given key.)
"Navigation" keys are assumed to change the cursor position, and
therefore don't cause automatic motion of the cursor as insertable
characters do.
._AddNavKeycode(keycode, handler=None)
._AddNavKey(char, handler=None)
Allows controls to specify other keys (and optional handlers)
to be treated as navigational characters. (eg. '.' in IpAddrCtrl)
._GetNavKeycodes() Returns the current list of navigational keycodes.
._SetNavKeycodes(key_func_tuples)
Allows replacement of the current list of keycode
processed as navigation keys, and bind associated
optional keyhandlers. argument is a list of key/handler
tuples. Passing a value of None for the handler in a
given tuple indicates that default processing for the key
is desired.
._FindField(pos) Returns the Field object associated with this position
in the control.
._FindFieldExtent(pos, getslice=False, value=None)
Returns edit_start, edit_end of the field corresponding
to the specified position within the control, and
optionally also returns the current contents of that field.
If value is specified, it will retrieve the slice the corresponding
slice from that value, rather than the current value of the
control.
._AdjustField(pos)
This is, the function that gets called for a given position
whenever the cursor is adjusted to leave a given field.
By default, it adjusts the year in date fields if mask is a date,
It can be overridden by a derived class to
adjust the value of the control at that time.
(eg. IpAddrCtrl reformats the address in this way.)
._Change() Called by internal EVT_TEXT handler. Return False to force
skip of the normal class change event.
._Keypress(key) Called by internal EVT_CHAR handler. Return False to force
skip of the normal class keypress event.
._LostFocus() Called by internal EVT_KILL_FOCUS handler
._OnKeyDown(event)
This is the default EVT_KEY_DOWN routine; it just checks for
"navigation keys", and if event.ControlDown(), it fires the
mixin's _OnChar() routine, as such events are not always seen
by the "cooked" EVT_CHAR routine.
._OnChar(event) This is the main EVT_CHAR handler for the
MaskedEditMixin.
The following routines are used to handle standard actions
for control keys:
_OnArrow(event) used for arrow navigation events
_OnCtrl_A(event) 'select all'
_OnCtrl_C(event) 'copy' (uses base control function, as copy is non-destructive)
_OnCtrl_S(event) 'save' (does nothing)
_OnCtrl_V(event) 'paste' - calls _Paste() method, to do smart paste
_OnCtrl_X(event) 'cut' - calls _Cut() method, to "erase" selection
_OnCtrl_Z(event) 'undo' - resets value to previous value (if any)
_OnChangeField(event) primarily used for tab events, but can be
used for other keys (eg. '.' in IpAddrCtrl)
_OnErase(event) used for backspace and delete
_OnHome(event)
_OnEnd(event)
The following routine provides a hook back to any class derivations, so that
they can react to parameter changes before any value is set/reset as a result of
those changes. (eg. masked.ComboBox needs to detect when the choices list is
modified, either implicitly or explicitly, so it can reset the base control
to have the appropriate choice list *before* the initial value is reset to match.)
_OnCtrlParametersChanged()
Accessor Functions
------------------
For convenience, each class derived from MaskedEditMixin should
define an accessors mixin, so that it exposes only those parameters
that make sense for the derivation. This is done with an intermediate
level of inheritance, ie:
class BaseMaskedTextCtrl( TextCtrl, MaskedEditMixin ):
class TextCtrl( BaseMaskedTextCtrl, MaskedEditAccessorsMixin ):
class ComboBox( BaseMaskedComboBox, MaskedEditAccessorsMixin ):
class NumCtrl( BaseMaskedTextCtrl, MaskedNumCtrlAccessorsMixin ):
class IpAddrCtrl( BaseMaskedTextCtrl, IpAddrCtrlAccessorsMixin ):
class TimeCtrl( BaseMaskedTextCtrl, TimeCtrlAccessorsMixin ):
etc.
Each accessors mixin defines Get/Set functions for the base class parameters
that are appropriate for that derivation.
This allows the base classes to be "more generic," exposing the widest
set of options, while not requiring derived classes to be so general.
"""
import copy
import difflib
import re
import string
import types
import wx
# jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would
# be a good place to implement the 2.3 logger class
from wx.tools.dbg import Logger
##dbg = Logger()
##dbg(enable=1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -