⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numctrl.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
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 + -