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

📄 numctrl.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
            if self._allowNone:
##                dbg('calling base BaseMaskedTextCtrl._SetValue(self, "%s")' % value)
                BaseMaskedTextCtrl._SetValue(self, value)
                self.Refresh()
                return
            elif self._min > 0 and self.IsLimited():
                replacement = self._min
            else:
                replacement = 0
##            dbg('empty value; setting replacement:', replacement)

        if replacement is None:
            # Go get the integer portion about to be set and verify its validity
            intstart, intend = self._fields[0]._extent
##            dbg('intstart, intend:', intstart, intend)
##            dbg('raw integer:"%s"' % value[intstart:intend])
            int = self._GetNumValue(value[intstart:intend])
            numval = self._fromGUI(value)

##            dbg('integer: "%s"' % int)
            try:
                fracval = self.GetFraction(value)
            except ValueError, e:
##                dbg('Exception:', e, 'must be out of bounds; disallow value')
                self._disallowValue()
##                dbg(indent=0)
                return

            if fracval == 0.0:
##                dbg('self._isNeg?', self._isNeg)
                if int == '-' and self._oldvalue < 0 and not self._typedSign:
##                    dbg('just a negative sign; old value < 0; setting replacement of 0')
                    replacement = 0
                    self._isNeg = False
                elif int[:2] == '-0' and self._fractionWidth == 0:
                    if self._oldvalue < 0:
##                        dbg('-0; setting replacement of 0')
                        replacement = 0
                        self._isNeg = False
                    elif not self._limited or (self._min < -1 and self._max >= -1):
##                        dbg('-0; setting replacement of -1')
                        replacement = -1
                        self._isNeg = True
                    else:
                        # limited and -1 is out of bounds
                        self._disallowValue()
##                        dbg(indent=0)
                        return

                elif int == '-' and (self._oldvalue >= 0 or self._typedSign) and self._fractionWidth == 0:
                    if not self._limited or (self._min < -1 and self._max >= -1):
##                        dbg('just a negative sign; setting replacement of -1')
                        replacement = -1
                    else:
                        # limited and -1 is out of bounds
                        self._disallowValue()
##                        dbg(indent=0)
                        return

                elif( self._typedSign
                      and int.find('-') != -1
                      and self._limited
                      and not self._min <= numval <= self._max):
                    # changed sign resulting in value that's now out-of-bounds;
                    # disallow
                    self._disallowValue()
##                    dbg(indent=0)
                    return

            if replacement is None:
                if int and int != '-':
                    try:
                        string.atol(int)
                    except ValueError:
                        # integer requested is not legal.  This can happen if the user
                        # is attempting to insert a digit in the middle of the control
                        # resulting in something like "   3   45". Disallow such actions:
##                        dbg('>>>>>>>>>>>>>>>> "%s" does not convert to a long!' % int)
                        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)
##                        dbg(indent=0)
                        return

                    if int[0] == '0' and len(int) > 1:
##                        dbg('numvalue: "%s"' % numvalue.replace(' ', ''))
                        if self._fractionWidth:
                            value = self._toGUI(string.atof(numvalue))
                        else:
                            value = self._toGUI(string.atol(numvalue))
##                        dbg('modified value: "%s"' % value)

        self._typedSign = False     # reset state var

        if replacement is not None:
            # Value presented wasn't a legal number, but control should do something
            # reasonable instead:
##            dbg('setting replacement value:', replacement)
            self._SetValue(self._toGUI(replacement))
            sel_start = BaseMaskedTextCtrl.GetValue(self).find(str(abs(replacement)))   # find where it put the 1, so we can select it
            sel_to = sel_start + len(str(abs(replacement)))
##            dbg('queuing selection of (%d, %d)' %(sel_start, sel_to))
            wx.CallAfter(self.SetInsertionPoint, sel_start)
            wx.CallAfter(self.SetSelection, sel_start, sel_to)
##            dbg(indent=0)
            return

        # Otherwise, apply appropriate formatting to value:

        # Because we're intercepting the value and adjusting it
        # before a sign change is detected, we need to do this here:
        if '-' in value or '(' in value:
            self._isNeg = True
        else:
            self._isNeg = False

##        dbg('value:"%s"' % value, 'self._useParens:', self._useParens)
        if self._fractionWidth:
            adjvalue = self._adjustFloat(self._GetNumValue(value).replace('.',self._decimalChar))
        else:
            adjvalue = self._adjustInt(self._GetNumValue(value))
##        dbg('adjusted value: "%s"' % adjvalue)


        sel_start, sel_to = self._GetSelection()     # record current insertion point
##        dbg('calling BaseMaskedTextCtrl._SetValue(self, "%s")' % adjvalue)
        BaseMaskedTextCtrl._SetValue(self, adjvalue)
        # After all actions so far scheduled, check that resulting cursor
        # position is appropriate, and move if not:
        wx.CallAfter(self._CheckInsertionPoint)

##        dbg('finished NumCtrl::_SetValue', indent=0)

    def _CheckInsertionPoint(self):
        # If current insertion point is before the end of the integer and
        # its before the 1st digit, place it just after the sign position:
##        dbg('NumCtrl::CheckInsertionPoint', indent=1)
        sel_start, sel_to = self._GetSelection()
        text = self._GetValue()
        if sel_to < self._fields[0]._extent[1] and text[sel_to] in (' ', '-', '('):
            text, signpos, right_signpos = self._getSignedValue()
##            dbg('setting selection(%d, %d)' % (signpos+1, signpos+1))
            self.SetInsertionPoint(signpos+1)
            self.SetSelection(signpos+1, signpos+1)
##        dbg(indent=0)


    def _OnErase( self, event=None, just_return_value=False ):
        """
        This overrides the base control _OnErase, so that erasing around
        grouping characters auto selects the digit before or after the
        grouping character, so that the erasure does the right thing.
        """
##        dbg('NumCtrl::_OnErase', indent=1)
        if event is None:   # called as action routine from Cut() operation.
            key = wx.WXK_DELETE
        else:
            key = event.GetKeyCode()
        #if grouping digits, make sure deletes next to group char always
        # delete next digit to appropriate side:
        if self._groupDigits:
            value = BaseMaskedTextCtrl.GetValue(self)
            sel_start, sel_to = self._GetSelection()

            if key == wx.WXK_BACK:
                # if 1st selected char is group char, select to previous digit
                if sel_start > 0 and sel_start < len(self._mask) and value[sel_start:sel_to] == self._groupChar:
                    self.SetInsertionPoint(sel_start-1)
                    self.SetSelection(sel_start-1, sel_to)

                # elif previous char is group char, select to previous digit
                elif sel_start > 1 and sel_start == sel_to and value[sel_start-1:sel_start] == self._groupChar:
                    self.SetInsertionPoint(sel_start-2)
                    self.SetSelection(sel_start-2, sel_to)

            elif key == wx.WXK_DELETE:
                if( sel_to < len(self._mask) - 2 + (1 *self._useParens)
                    and sel_start == sel_to
                    and value[sel_to] == self._groupChar ):
                    self.SetInsertionPoint(sel_start)
                    self.SetSelection(sel_start, sel_to+2)

                elif( sel_to < len(self._mask) - 2 + (1 *self._useParens)
                           and value[sel_start:sel_to] == self._groupChar ):
                    self.SetInsertionPoint(sel_start)
                    self.SetSelection(sel_start, sel_to+1)
##        dbg(indent=0)
        return BaseMaskedTextCtrl._OnErase(self, event, just_return_value)


    def OnTextChange( self, event ):
        """
        Handles an event indicating that the text control's value
        has changed, and issue EVT_NUM event.
        NOTE: using wxTextCtrl.SetValue() to change the control's
        contents from within a EVT_CHAR handler can cause double
        text events.  So we check for actual changes to the text
        before passing the events on.
        """
##        dbg('NumCtrl::OnTextChange', indent=1)
        if not BaseMaskedTextCtrl._OnTextChange(self, event):
##            dbg(indent=0)
            return

        # else... legal value

        value = self.GetValue()
        if value != self._oldvalue:
            try:
                self.GetEventHandler().ProcessEvent(
                    NumberUpdatedEvent( self.GetId(), self.GetValue(), self ) )
            except ValueError:
##                dbg(indent=0)
                return
            # let normal processing of the text continue
            event.Skip()
        self._oldvalue = value # record for next event
##        dbg(indent=0)

    def _GetValue(self):
        """
        Override of BaseMaskedTextCtrl to allow mixin to get the raw text value of the
        control with this function.
        """
        return wx.TextCtrl.GetValue(self)


    def GetValue(self):
        """
        Returns the current numeric value of the control.
        """
        return self._fromGUI( BaseMaskedTextCtrl.GetValue(self) )

    def SetValue(self, value):
        """
        Sets the value of the control to the value specified.
        The resulting actual value of the control may be altered to
        conform with the bounds set on the control if limited,
        or colored if not limited but the value is out-of-bounds.
        A ValueError exception will be raised if an invalid value
        is specified.
        """
##        dbg('NumCtrl::SetValue(%s)' % value, indent=1)
        BaseMaskedTextCtrl.SetValue( self, self._toGUI(value) )
##        dbg(indent=0)


    def SetIntegerWidth(self, value):
        self.SetParameters(integerWidth=value)
    def GetIntegerWidth(self):
        return self._integerWidth

    def SetFractionWidth(self, value):
        self.SetParameters(fractionWidth=value)
    def GetFractionWidth(self):
        return self._fractionWidth



    def SetMin(self, min=None):
        """
        Sets the minimum value of the control.  If a value of None
        is provided, then the control will have no explicit minimum value.
        If the value specified is greater than the current maximum value,
        then the function returns False and the minimum will not change from
        its current setting.  On success, the function returns True.

        If successful and the current value is lower than the new lower
        bound, if the control is limited, the value will be automatically
        adjusted to the new minimum value; if not limited, the value in the
        control will be colored as invalid.

        If min > the max value allowed by the width of the control,
        the function will return False, and the min will not be set.
        """
##        dbg('NumCtrl::SetMin(%s)' % repr(min), indent=1)
        if( self._max is None
            or min is None
            or (self._max is not None and self._max >= min) ):
            try:
                self.SetParameters(min=min)
                bRet = True
            except ValueError:
                bRet = False
        else:
            bRet = False
##        dbg(indent=0)
        return bRet

    def GetMin(self):
        """
        Gets the lower bound value of the control.  It will return
        None if not specified.
        """
        return self._min


    def SetMax(self, max=None):
        """
        Sets the maximum value of the control. If a value of None
        is provided, then the control will have no explicit maximum value.
        If the value specified is less than the current minimum value, then
        the function returns False and the maximum will not change from its
        current setting. On success, the function returns True.

        If successful and the current value is greater than the new upper
        bound, if the control is limited the value will be automatically
        adjusted to this maximum value; if not limited, the value in the
        control will be colored as invalid.

        If max > the max value allowed by the width of the control,
        the function will return False, and the max will not be set.

⌨️ 快捷键说明

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