wxNumCtrl?

wxPyrts,

Has anyone written a decent numeric entry control, similar to wxTextCtrl,
but whose values can be ints? (or naturals, floats, etc.) I couldn't
find one in the wxPython demo or the wxWindows doc, and though there's
the rudiments of an example for a similar derived control in the
wxPyWiki cookbook, but it's not really a fully functional example.

I started rolling my own, but there are so many special cases, such as:

- handling [selections followed by] deletions that make the resulting
   value not a legal number (eg. "blank")
- handling dynamic range limits for the control
- allowing minus signs, but only in the right place, coupled with
   the deletion logic,
- enforcing a decimal for floating point values, etc.

that I started to wonder if this might be an "already-solved problem."
Has anyone done it? (All I really need is an natural number entry
control, but I'd like to dynamically alter the "range limits" on the
control based on other GUI activity.)

Thanks in advance,
/Will Sadkin
Parlance Corporation

The following code will NOT do all that you want, and I am not
entirely happy with it yet myself, but FWIW here are two related
wrappers on which I have been working. ('Text' and 'Decimal' are
two classes of data cell in my abstraction layer.)

class TextField(wx.wxTextCtrl):

    data = Text
    def __init__(self, parent, text, pos, size,
                 style, ref):
        wx.wxTextCtrl.__init__(self, parent, -1, text, pos, size)
        if isinstance(ref, self.data):
            self._ref = ref
        else:
            self._ref = self.data()
        self._ref._addObserver(self)
        self.Update()
        self.BindEvents()

    def BindEvents(self):
        wx.EVT_KILL_FOCUS(self, self.onLoseFocus)
        wx.EVT_CHAR(self, self.OnChar)

    def Update(self):
        self.SetValue(self._ref.Get())

    def onLoseFocus(self, event):
        self._ref.Set(self.GetValue())
        event.Skip()

    def OnChar(self, event):
        event.Skip()

class DecimalField(TextField):

    data = Decimal

    def OnChar(self, event):
        key = event.GetKeyCode()
        # test for numeric character keys
        if key > 47 and key < 58:
            event.Skip()
        # test for period (decimal point)
        elif key == 46:
            if '.' not in self.GetValue():
                if self.GetInsertionPoint() == 0:
                    # add 0 before leading decimal point
                    self.WriteText("0")
                event.Skip()
        # test for <Backspace> and <Delete>
        elif key == 8 or key == 127:
            event.Skip()
        # test for <left arrow> and <right arrow>
        elif key == 316 or key == 318:
            event.Skip()

···

--- Will Sadkin <wsadkin@nameconnector.com> wrote:

wxPyrts,

Has anyone written a decent numeric entry control, similar to
wxTextCtrl, but whose values can be ints? (or naturals, floats,
etc.) I couldn't find one in the wxPython demo or the wxWindows
doc, and though there's the rudiments of an example for a
similar derived control in the wxPyWiki cookbook, but it's not
really a fully functional example.

I started rolling my own, but there are so many special cases,
such as:

- handling [selections followed by] deletions that make the
   resulting value not a legal number (eg. "blank")
- handling dynamic range limits for the control
- allowing minus signs, but only in the right place, coupled
   with the deletion logic,
- enforcing a decimal for floating point values, etc.

that I started to wonder if this might be an "already-solved
problem." Has anyone done it? (All I really need is an
natural number entry control, but I'd like to dynamically
alter the "range limits" on the control based on other GUI
activity.)

=====
Donnal Walter
Arkansas Children's Hospital

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.

Will Sadkin <wsadkin@nameconnector.com> writes:

> wxPyrts,
>
> Has anyone written a decent numeric entry control, similar to wxTextCtrl,
> but whose values can be ints? (or naturals, floats, etc.) I couldn't
> find one in the wxPython demo or the wxWindows doc, and though there's
> the rudiments of an example for a similar derived control in the
> wxPyWiki cookbook, but it's not really a fully functional example.
>
> ...

Wouldn't the easiest way be to intercept text change event and just check
if the value still is a valid number and if not just change the value
back to the latest "sane" value?

warning, pseudoish code below...

def OnTextChange(self,evt):
  try:
    int(self.GetValue())
    self.oldval=self.GetValue()
  except:
    self.SetValue(self.oldval)
  # hmm... we must stop the usual texthandling, does this work?
  evt.SetString("")

···

--
  Pierre Hjälm, Systems Administrator
  Department of Information Science, Uppsala University, Sweden
  email:pierre.hjalm@dis.uu.se phone:+46-(0)18-4711044 fax:+46-(0)18-554422