validate on a ComboBox

Hi,

I would like to check the user input in a ComboBox.
For this I try to use a validator.
After some searching on the web I found an example
from which I made the code below.

I would like to limit the user input to two digits
representing a value between 0 to 99.

I see no effect?

Linux 2.6.22.19-0.1-default
Python 2.5.1
wx.Python 2.8.7.1

···

-------------------------
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Validator example
# Muk 05.02.2009: start

"""validator example"""

import wx

class Validator(wx.Frame):
    """frame contains a ComboBox with validator"""
    def __init__(self):
# """frame contains a ComboBox with validator"""
        wx.Frame.__init__(self, None, wx.ID_ANY, "my frame")
        self.panel = wx.Panel(self, wx.ID_ANY)
        # controls
        val99 = Int99Validator
        self.cbx_validator = wx.ComboBox( self.panel, wx.ID_ANY, choices=['0'], size=(150, 30), validator=val99())
        self.txt_validator = wx.StaticText( self.panel, wx.ID_ANY, label='validator', size=(150, 30), style=wx.ALIGN_RIGHT)
        self.siz_top = wx.BoxSizer(wx.VERTICAL)
        self.siz_top.Add(self.txt_validator, 0, wx.ALL, 5)
        self.siz_top.Add(self.cbx_validator, 0, wx.ALL, 5)
        # bindings
        self.Bind(wx.EVT_TEXT, self.on_cbx_validator, self.cbx_validator)
        # layout
        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(self.siz_top)
        self.panel.Layout()

    def on_cbx_validator(self, evt):
        """EVT_TEXT in cbx_validator"""
        value = self.cbx_validator.GetValue()
        print("on_cbx_validator out: value=%s" % (str(value)))
        evt.Skip()

class Int99Validator(wx.PyValidator):
    """Validator to check if GetValue() provides an integer value 0..99"""
    def Clone(self):
        """Clone ???"""
        return self.__class__()
    def Validate(self, window):
        """Validate ???"""
# window = wx.PyTypeCast(window, "wx.ComboBox") # pylint says: "Module 'wx' has no 'PyTypeCast' member"
        try:
            value = int(window.GetValue(), 10)
            if value < 0:
                raise ValueError
            if value > 99:
                raise ValueError
            return True
        except ValueError:
            return False

if __name__ == "__main__":
    APP = wx.PySimpleApp()
    FRAME = Validator().Show()
    APP.MainLoop()
-------------------------

Thanks in advance
--
Kurt Mueller

Hi Kurt,

Kurt Mueller wrote:

Hi,

I would like to check the user input in a ComboBox.
For this I try to use a validator.
After some searching on the web I found an example
from which I made the code below.

I would like to limit the user input to two digits
representing a value between 0 to 99.

I see no effect?
  

Have a look at the validator demo in the wxPython demo.

I think for what you want to do you need to bind the event in your validator.

Werner

Werner F. Bruhin schrieb:

Have a look at the validator demo in the wxPython demo.
I think for what you want to do you need to bind the event in your
validator.

Thanks.

I took some code of the (your) validator demo (it is on my own disk,
shame on me).
It checks the characters typed in according to the setting of the flag.
Now I would like to check also the int value of the digits already typed in.

My current test code:

···

-----------------------
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Validator example
# Muk 05.02.2009: start
# Muk 05.02.2009 14:33: second try

"""validator test code"""

import wx
import string

ALPHA_ONLY = 1
DIGIT_ONLY = 2

class ValidatorTest(wx.Frame):
    """frame contains a ComboBox with validator"""
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "my frame")
        self.panel = wx.Panel(self, wx.ID_ANY)
        self.cbx_validator = wx.ComboBox( self.panel, wx.ID_ANY,
choices=['0'], size=(150, 30), validator=Int99Validator(DIGIT_ONLY))
        self.txt_validator = wx.StaticText( self.panel, wx.ID_ANY,
label='validator', size=(150, 30), style=wx.ALIGN_RIGHT)
        self.siz_top = wx.BoxSizer(wx.VERTICAL)
        self.siz_top.Add(self.txt_validator, 0, wx.ALL, 5)
        self.siz_top.Add(self.cbx_validator, 0, wx.ALL, 5)
        self.Bind(wx.EVT_TEXT, self.on_cbx_validator, self.cbx_validator)
        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(self.siz_top)
        self.panel.Layout()

    def on_cbx_validator(self, evt):
        """EVT_TEXT in cbx_validator"""
        val99 = Int99Validator()
        print("self.cbx_validator.Validate=%s" %
(self.cbx_validator.Validate()))
        value = self.cbx_validator.GetValue()
        print("on_cbx_validator out: value=%s" % (str(value)))
        evt.Skip()

class Int99Validator(wx.PyValidator):
    def __init__(self, flag=None):
        """Validator to check if GetValue() provides an integer value
0..99"""
        wx.PyValidator.__init__(self)
        self.flag = flag
        self.Bind(wx.EVT_CHAR, self.OnChar)
    def Clone(self):
        return self.__class__(self.flag)
    def Validate(self, window):
        print("Int99Validator.Validate: self=%s, window=%s" %
(repl(self), repr(window)))
        value = window.GetWindow().GetValue()
        print("Int99Validator.Validate: value=%s" % (str(value)))
        try:
            value = int(window.GetValue(), 10)
            if value < 0:
                return False
            if value > 99:
                return False
            return True
        except ValueError:
            return False

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
            evt.Skip()
            return
        if self.flag == ALPHA_ONLY and chr(key) in string.letters:
            evt.Skip()
            return
        if self.flag == DIGIT_ONLY and chr(key) in string.digits:
            evt.Skip()
            return
        if not wx.Validator_IsSilent():
            wx.Bell()
        # Returning without calling evt.Skip eats the evt before it
        # gets to the text control
        return

if __name__ == "__main__":
    APP = wx.PySimpleApp()
    FRAME = ValidatorTest().Show()
    APP.MainLoop()
-----------------------

TIA
--
Kurt Mueller

Kurt Mueller wrote:

Werner F. Bruhin schrieb:
  

Have a look at the validator demo in the wxPython demo.
I think for what you want to do you need to bind the event in your
validator.
    

Thanks.

I took some code of the (your) validator demo (it is on my own disk,
shame on me).
It checks the characters typed in according to the setting of the flag.
Now I would like to check also the int value of the digits already typed in.
  

<snip>

You might want to look at the MaskedEditControls too. They have a couple of combobox examples in that demo under the "Other masked controls" tab. Or you could just do this instead:

choices = [x for x in range(100)]
myCombo = wx.ComboBox( self.panel, wx.ID_ANY, choices=choices, size=(150, 30), style=wx.CB_READONLY)

You'd probably need to set the wx.CB_READONLY style to prevent the user from putting in their own number or text (as I did above).

···

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

Mike Driscoll schrieb:

You might want to look at the MaskedEditControls too. They have a
couple of combobox examples in that demo under the "Other masked
controls" tab. Or you could just do this instead:
choices = [x for x in range(100)]
myCombo = wx.ComboBox( self.panel, wx.ID_ANY, choices=choices,
size=(150, 30), style=wx.CB_READONLY)
You'd probably need to set the wx.CB_READONLY style to prevent the
user from putting in their own number or text (as I did above).

Thanks Mike.

I just found out, that I cannot use the standard ComboBox
because one cannot modify the choices list and I have to.

So I nedd to redesign my GUI or use some of the other
ComboBoxes like ExtendedChoice or the MaskedEditControls.

···

****

Grüessli
--
Kurt Mueller

What do you mean by "one cannot modify the choices list"? wx.ComboBox
inherits from wxControlWithItems, which has Append, Clear and Delete
methods. You should be able to use those to change the choices
available.

Simon

···

-----Original Message-----
From: wxpython-users-bounces@lists.wxwidgets.org
[mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf
Of Kurt Mueller
Sent: 06 February 2009 07:47
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users] validate on a ComboBox --second try--

Mike Driscoll schrieb:
> You might want to look at the MaskedEditControls too. They have a
> couple of combobox examples in that demo under the "Other masked
> controls" tab. Or you could just do this instead:
> choices = [x for x in range(100)]
> myCombo = wx.ComboBox( self.panel, wx.ID_ANY, choices=choices,
> size=(150, 30), style=wx.CB_READONLY)
> You'd probably need to set the wx.CB_READONLY style to prevent the
> user from putting in their own number or text (as I did above).
Thanks Mike.

I just found out, that I cannot use the standard ComboBox
because one cannot modify the choices list and I have to.

So I nedd to redesign my GUI or use some of the other
ComboBoxes like ExtendedChoice or the MaskedEditControls.

King Simon-NFHD78 schrieb:

What do you mean by "one cannot modify the choices list"? wx.ComboBox
inherits from wxControlWithItems, which has Append, Clear and Delete
methods. You should be able to use those to change the choices
available.

Oooohhh my goodness!
That was a bad day for me yesterday.

Thank you very much!

···

--
Kurt Mueller