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

📄 numctrl.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
                    if self._fractionWidth != kwargs['fractionWidth']:
                        self._fractionWidth = kwargs['fractionWidth']

            if self._fractionWidth:
                fracmask = '.' + '#{%d}' % self._fractionWidth
                fields[1] = Field(defaultValue='0'*self._fractionWidth)
                emptyInvalid = False
            else:
                emptyInvalid = True
                fracmask = ''
##            dbg('fracmask:', fracmask)

            if kwargs.has_key('integerWidth'):
                if type(kwargs['integerWidth']) != types.IntType:
##                    dbg(indent=0)
                    raise AttributeError('invalid integerWidth (%s) specified; expected integer' % repr(kwargs['integerWidth']))
                elif kwargs['integerWidth'] < 0:
##                    dbg(indent=0)
                    raise AttributeError('invalid integerWidth (%s) specified; must be > 0' % repr(kwargs['integerWidth']))
                else:
                    self._integerWidth = kwargs['integerWidth']

            if kwargs.has_key('groupDigits'):
                self._groupDigits = kwargs['groupDigits']

            if self._groupDigits:
                self._groupSpace = (self._integerWidth - 1) / 3
            else:
                self._groupSpace = 0

            intmask = '#{%d}' % (self._integerWidth + self._groupSpace)
##            dbg('intmask:', intmask)
            fields[0] = Field(formatcodes='r<>', emptyInvalid=emptyInvalid)
            maskededit_kwargs['fields'] = fields

            # don't bother to reprocess these arguments:
            if kwargs.has_key('integerWidth'):
                del kwargs['integerWidth']
            if kwargs.has_key('fractionWidth'):
                del kwargs['fractionWidth']

            maskededit_kwargs['mask'] = intmask+fracmask

        if kwargs.has_key('groupChar') or kwargs.has_key('decimalChar'):
            old_groupchar = self._groupChar     # save so we can reformat properly
            old_decimalchar = self._decimalChar
##            dbg("old_groupchar: '%s'" % old_groupchar)
##            dbg("old_decimalchar: '%s'" % old_decimalchar)
            groupchar = old_groupchar
            decimalchar = old_decimalchar
            old_numvalue = self._GetNumValue(self._GetValue())

            if kwargs.has_key('groupChar'):
                maskededit_kwargs['groupChar'] = kwargs['groupChar']
                groupchar = kwargs['groupChar']
            if kwargs.has_key('decimalChar'):
                maskededit_kwargs['decimalChar'] = kwargs['decimalChar']
                decimalchar = kwargs['decimalChar']

            # Add sanity check to make sure these are distinct, and if not,
            # raise attribute error
            if groupchar == decimalchar:
                raise AttributeError('groupChar and decimalChar must be distinct')


        # for all other parameters, assign keyword args as appropriate:
        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)
            elif key not in MaskedEditMixin.valid_ctrl_params.keys():
                setattr(self, '_' + key, param_value)
            elif key in ('mask', 'autoformat'): # disallow explicit setting of mask
                raise AttributeError('invalid keyword argument "%s"' % key)
            else:
                maskededit_kwargs[key] = param_value
##        dbg('kwargs:', kwargs)

        # reprocess existing format codes to ensure proper resulting format:
        formatcodes = self.GetCtrlParameter('formatcodes')
        if kwargs.has_key('allowNegative'):
            if kwargs['allowNegative'] and '-' not in formatcodes:
                formatcodes += '-'
                maskededit_kwargs['formatcodes'] = formatcodes
            elif not kwargs['allowNegative'] and '-' in formatcodes:
                formatcodes = formatcodes.replace('-','')
                maskededit_kwargs['formatcodes'] = formatcodes

        if kwargs.has_key('groupDigits'):
            if kwargs['groupDigits'] and ',' not in formatcodes:
                formatcodes += ','
                maskededit_kwargs['formatcodes'] = formatcodes
            elif not kwargs['groupDigits'] and ',' in formatcodes:
                formatcodes = formatcodes.replace(',','')
                maskededit_kwargs['formatcodes'] = formatcodes

        if kwargs.has_key('selectOnEntry'):
            self._selectOnEntry = kwargs['selectOnEntry']
##            dbg("kwargs['selectOnEntry']?", kwargs['selectOnEntry'], "'S' in formatcodes?", 'S' in formatcodes)
            if kwargs['selectOnEntry'] and 'S' not in formatcodes:
                formatcodes += 'S'
                maskededit_kwargs['formatcodes'] = formatcodes
            elif not kwargs['selectOnEntry'] and 'S' in formatcodes:
                formatcodes = formatcodes.replace('S','')
                maskededit_kwargs['formatcodes'] = formatcodes

        if kwargs.has_key('autoSize'):
            self._autoSize = kwargs['autoSize']
            if kwargs['autoSize'] and 'F' not in formatcodes:
                formatcodes += 'F'
                maskededit_kwargs['formatcodes'] = formatcodes
            elif not kwargs['autoSize'] and 'F' in formatcodes:
                formatcodes = formatcodes.replace('F', '')
                maskededit_kwargs['formatcodes'] = formatcodes


        if 'r' in formatcodes and self._fractionWidth:
            # top-level mask should only be right insert if no fractional
            # part will be shown; ie. if reconfiguring control, remove
            # previous "global" setting.
            formatcodes = formatcodes.replace('r', '')
            maskededit_kwargs['formatcodes'] = formatcodes


        if kwargs.has_key('limited'):
            if kwargs['limited'] and not self._limited:
                maskededit_kwargs['validRequired'] = True
            elif not kwargs['limited'] and self._limited:
                maskededit_kwargs['validRequired'] = False
            self._limited = kwargs['limited']

##        dbg('maskededit_kwargs:', maskededit_kwargs)
        if maskededit_kwargs.keys():
            self.SetCtrlParameters(**maskededit_kwargs)

        # Go ensure all the format codes necessary are present:
        orig_intformat = intformat = self.GetFieldParameter(0, 'formatcodes')
        if 'r' not in intformat:
            intformat += 'r'
        if '>' not in intformat:
            intformat += '>'
        if intformat != orig_intformat:
            if self._fractionWidth:
                self.SetFieldParameters(0, formatcodes=intformat)
            else:
                self.SetCtrlParameters(formatcodes=intformat)

        # Record end of integer and place cursor there unless selecting, or select entire field:
        integerStart, integerEnd = self._fields[0]._extent
        if not self._fields[0]._selectOnFieldEntry:
            self.SetInsertionPoint(0)
            self.SetInsertionPoint(integerEnd)
            self.SetSelection(integerEnd, integerEnd)
        else:
            self.SetInsertionPoint(0)   # include any sign
            self.SetSelection(0, integerEnd)


        # Set min and max as appropriate:
        if kwargs.has_key('min'):
            min = kwargs['min']
            if( self._max is None
                or min is None
                or (self._max is not None and self._max >= min) ):
##                dbg('examining min')
                if min is not None:
                    try:
                        textmin = self._toGUI(min, apply_limits = False)
                    except ValueError:
##                        dbg('min will not fit into control; ignoring', indent=0)
                        raise
##                dbg('accepted min')
                self._min = min
            else:
##                dbg('ignoring min')
                pass


        if kwargs.has_key('max'):
            max = kwargs['max']
            if( self._min is None
                or max is None
                or (self._min is not None and self._min <= max) ):
##                dbg('examining max')
                if max is not None:
                    try:
                        textmax = self._toGUI(max, apply_limits = False)
                    except ValueError:
##                        dbg('max will not fit into control; ignoring', indent=0)
                        raise
##                dbg('accepted max')
                self._max = max
            else:
##                dbg('ignoring max')
                pass

        if kwargs.has_key('allowNegative'):
            self._allowNegative = kwargs['allowNegative']

        # Ensure current value of control obeys any new restrictions imposed:
        text = self._GetValue()
##        dbg('text value: "%s"' % text)
        if kwargs.has_key('groupChar') and self._groupChar != old_groupchar and text.find(old_groupchar) != -1:
            text = old_numvalue
##            dbg('old_groupchar: "%s" newgroupchar: "%s"' % (old_groupchar, self._groupChar))
        if kwargs.has_key('decimalChar') and self._decimalChar != old_decimalchar and text.find(old_decimalchar) != -1:
            text = old_numvalue
        
        if text != self._GetValue():
            if self._decimalChar != '.':
                # ensure latest decimal char is in "numeric value" so it won't be removed
                # when going to the GUI:
                text = text.replace('.', self._decimalChar)
            newtext = self._toGUI(text)
##            dbg('calling wx.TextCtrl.SetValue(self, %s)' % newtext)
            wx.TextCtrl.SetValue(self, newtext)

        value = self.GetValue()

##        dbg('self._allowNegative?', self._allowNegative)
        if not self._allowNegative and self._isNeg:
            value = abs(value)
##            dbg('abs(value):', value)
            self._isNeg = False

        elif not self._allowNone and BaseMaskedTextCtrl.GetValue(self) == '':
            if self._min > 0:
                value = self._min
            else:
                value = 0

        sel_start, sel_to = self.GetSelection()
        if self.IsLimited() and self._min is not None and value < self._min:
##            dbg('Set to min value:', self._min)
            self._SetValue(self._toGUI(self._min))

        elif self.IsLimited() and self._max is not None and value > self._max:
##            dbg('Setting to max value:', self._max)
            self._SetValue(self._toGUI(self._max))
        else:
            # reformat current value as appropriate to possibly new conditions
##            dbg('Reformatting value:', value)
            sel_start, sel_to = self.GetSelection()
            self._SetValue(self._toGUI(value))
        self.Refresh() # recolor as appropriate
##        dbg('finished NumCtrl::SetParameters', indent=0)



    def _GetNumValue(self, value):
        """
        This function attempts to "clean up" a text value, providing a regularized
        convertable string, via atol() or atof(), for any well-formed numeric text value.
        """
        return value.replace(self._groupChar, '').replace(self._decimalChar, '.').replace('(', '-').replace(')','').strip()


    def GetFraction(self, candidate=None):
        """
        Returns the fractional portion of the value as a float.  If there is no
        fractional portion, the value returned will be 0.0.
        """
        if not self._fractionWidth:
            return 0.0
        else:
            fracstart, fracend = self._fields[1]._extent
            if candidate is None:
                value = self._toGUI(BaseMaskedTextCtrl.GetValue(self))
            else:
                value = self._toGUI(candidate)
            fracstring = value[fracstart:fracend].strip()
            if not value:
                return 0.0
            else:
                return string.atof(fracstring)

    def _OnChangeSign(self, event):
##        dbg('NumCtrl::_OnChangeSign', indent=1)
        self._typedSign = True
        MaskedEditMixin._OnChangeSign(self, event)
##        dbg(indent=0)


    def _disallowValue(self):
##        dbg('NumCtrl::_disallowValue')
        # limited and -1 is out of bounds
        if self._typedSign:
            self._isNeg = False
        if not wx.Validator_IsSilent():
            wx.Bell()
        sel_start, sel_to = self._GetSelection()
##        dbg('queuing reselection of (%d, %d)' % (sel_start, sel_to))
        wx.CallAfter(self.SetInsertionPoint, sel_start)      # preserve current selection/position
        wx.CallAfter(self.SetSelection, sel_start, sel_to)

    def _SetValue(self, value):
        """
        This routine supersedes the base masked control _SetValue().  It is
        needed to ensure that the value of the control is always representable/convertable
        to a numeric return value (via GetValue().)  This routine also handles
        automatic adjustment and grouping of the value without explicit intervention
        by the user.
        """

##        dbg('NumCtrl::_SetValue("%s")' % value, indent=1)

        if( (self._fractionWidth and value.find(self._decimalChar) == -1) or
            (self._fractionWidth == 0 and value.find(self._decimalChar) != -1) ) :
            value = self._toGUI(value)

        numvalue = self._GetNumValue(value)
##        dbg('cleansed value: "%s"' % numvalue)
        replacement = None

        if numvalue == "":

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -