HowToCreateANumbersOnlyControl

From Dabo Wiki
Jump to: navigation, search

The following class was writtern by Larry Long, Nate Lowrie and John Fabiani.

RANumBox(self, RegID=ncostID, MinValue=0.00, MaxValue=999999.99, IntegerWidth=6, DecimalWidth=2, Alignment="R") is the line of code that uses the class.

Where MinValue, MaxValue, IntegerWidth, DecimalWidth will determine the imput mask. Run the code below (you may not see the background color change on linux)

The class is sub-classed on dTextBox.

import re
import dabo
import dabo.dEvents as dEvents
import dabo.dException as dException
from dabo.dLocalize import _
dabo.ui.loadUI('wx')


class RANumBox(dabo.ui.dTextBox):
    def afterInit(self):
        self.Alignment='Right'

    def onKeyChar(self,evt):
        from dabo.ui import dKeys as dKeys
        keyChar = evt.keyChar
        if evt.keyCode in range(32,126) and not str.isdigit(keyChar) and not keyChar=='.':
            evt.stop()
        if keyChar=='.' and not self.GetValue().find('.')==-1:
            evt.stop()
        dabo.ui.callAfter(self.Validate)

    def Validate(self):
        try:
            value = float(self.GetValue())
        except:
            return

        if (self.MinValue is not None and value < self.MinValue) or (
                self.MaxValue is not None and value > self.MaxValue):
            self.BackColor = "pink"
            return
        else:
            self.BackColor = "white"

        pattern = ''
        if self.IntegerWidth is not None:
            pattern='^([0-9]{0,%s})' % (self.IntegerWidth,)
        else:
            pattern='^([0-9]{0,})'

        if self.DecimalWidth is not None:
            pattern = pattern + '(\.[0-9]{0,%s})' % (self.DecimalWidth,)
        else:
            pattern=pattern +'(\.[0-9]{0,})'
        pattern = pattern +'?$'

        if re.match(pattern, self.GetValue())==None:
            self.BackColor = "pink"
        else:
            self.BackColor = "white"

    def _getDecimalWidth(self):
        try:
            return(self._decimalWidth)
        except:
            return(None)

    def _setDecimalWidth(self, val):
        self._decimalWidth = val

    def _getIntegerWidth(self):
        try:
            return(self._integerWidth)
        except:
            return None

    def _setIntegerWidth(self, val):
        self._integerWidth = val

    def _getMinValue(self):
        try:
            return(self._minValue)
        except:
            return(None)

    def _setMinValue(self, val):
        self._minValue = val

    def _getMaxValue(self):
        try:
            return(self._maxValue)
        except:
            return(None)

    def _setMaxValue(self, val):
        self._maxValue = val
    def _getEditable(self):
        try:
            return getattr(self, "_Editable", None)
        except:
            return(None)

    def _setEditable(self, val):
        self._Editable = val


    DecimalWidth = property(_getDecimalWidth, _setDecimalWidth, None,
           "The number of digits after the decimal point (int)")

    Editable = property(_getEditable, _setEditable)

    IntegerWidth = property(_getIntegerWidth, _setIntegerWidth, None,
           "The number of digits before the decimal point (int)")

    MinValue = property(_getMinValue, _setMinValue, None,
           "The minimum value that the entered data can be (int)")

    MaxValue = property(_getMaxValue, _setMaxValue, None,
           "The maximum value that the entered data can be (int)")


class MainForm(dabo.ui.dForm):
    def afterInit(self):
        self.Sizer = hs = dabo.ui.dSizer('h')
        hs.append(dabo.ui.dLabel(self, Caption='Cost   '),alignment='Right')
        hs.append(RANumBox(self,RegID='ncostID', MinValue=0.00, MaxValue=999999.99,
                IntegerWidth=6, DecimalWidth=2, Alignment='R'))


if __name__ == "__main__":
        app = dabo.dApp()
        app.BasePrefKey = "NumberBox Test"
        app.setAppInfo("appName", "NumberBox Test")
        app.MainFormClass = MainForm
        app.start()