Adding Validation to wx.TextEntryDialog

Is there any way to add a validator to a wx.TextEntryDialog?
I tried using SetValidator() in the __init__ of a class inheriting
from wx.TextEntryDialog, but my Validate() method didn't seem
to get called on the OK press. I'll contrive and post a code
example is the answer to my question should be "yes."

thanks!

Dave

David A. Barrett wrote:

Is there any way to add a validator to a wx.TextEntryDialog?
I tried using SetValidator() in the __init__ of a class inheriting
from wx.TextEntryDialog, but my Validate() method didn't seem
to get called on the OK press. I'll contrive and post a code
example is the answer to my question should be "yes."

You need to attach the validator to the text ctrl. It's not documented but it looks like it is always created with an ID of 3000, so you can get a reference to the textctrl with:

  txtctrl = dlg.FindWindowById(3000)

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

You need to attach the validator to the text ctrl. It's not documented but it looks like it is always created with an ID of 3000, so you can get a reference to the textctrl with:

    txtctrl = dlg.FindWindowById(3000)

Impressive response time. Thanks! Answering these sorts of
questions when they come up has been expensive for me--enough
that I've tried examining the python source code for wx.

I'm curious, how did you come up with that answer so quickly?

Perhaps there a way for the swig-ignorant to navigate the wx code?
(e.g. is there a web api similar to the linux kernel source tree?)

Dave

Mortimer P. Schnurd wrote:

Robin Dunn wrote:

You need to attach the validator to the text ctrl. It's not documented but it looks like it is always created with an ID of 3000, so you can get a reference to the textctrl with:

    txtctrl = dlg.FindWindowById(3000)

Impressive response time. Thanks! Answering these sorts of
questions when they come up has been expensive for me--enough
that I've tried examining the python source code for wx.

I'm curious, how did you come up with that answer so quickly?

I knew exactly where to look. :wink:

Perhaps there a way for the swig-ignorant to navigate the wx code?
(e.g. is there a web api similar to the linux kernel source tree?)

Is something like this what you mean? http://cvs.wxwidgets.org/viewcvs.cgi/wxWidgets/

It hopefully will be moving to subversion by early next week and then the URL will be: http://svn.wxwidgets.org/viewvc/wxWidgets/

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn <robin <at> alldunn.com> writes:

David A. Barrett wrote:
> Is there any way to add a validator to a wx.TextEntryDialog?
> I tried using SetValidator() in the __init__ of a class inheriting
> from wx.TextEntryDialog, but my Validate() method didn't seem
> to get called on the OK press. I'll contrive and post a code
> example is the answer to my question should be "yes."

You need to attach the validator to the text ctrl. It's not documented
but it looks like it is always created with an ID of 3000, so you can
get a reference to the textctrl with:

  txtctrl = dlg.FindWindowById(3000)

I set my simple Validator for TextEntryDialog, but now is Ok-Button
functionless. What's wrong here?

import string
import wx

class CharValidator(wx.PyValidator):
    def __init__(self, flag):
        wx.PyValidator.__init__(self)
        self.flag = flag
        self.Bind(wx.EVT_CHAR, self.OnChar)
        return
    
    def Clone(self):
        '''
        every validator must implement Clone() method!
        '''
        return CharValidator(self.flag)
    
    def Validate(self, win):
        valid = False
        textCtrl = self.Window
        value = textCtrl.Value
        if self.flag == LETTERS:
            for x in value:
                if x not in string.letters:
                    pass
        elif self.flag == DECIMAL_DIGITS:
            for x in value:
                if x not in string.digits:
                    pass
        elif self.flag == HEX_DIGITS:
            for x in value:
                if x not in string.hexdigits:
                    pass
        else:
            valid = True
        return valid
    
    def TransferToWindow(self):
        return True
    
    def TransferFromWindow(self):
        return True
    
    def OnChar(self, event):
        keyCode = event.GetKeyCode()
        if keyCode in range(256) and keyCode not in (8, 127):
        #8 = Backspace-Key, 127 = Delete-Key
            key = chr(event.GetKeyCode())
            if self.flag == DECIMAL_DIGITS and key not in string.digits:
                return
            if self.flag == LETTERS and key not in string.letters:
                return
            if self.flag == HEX_DIGITS and key not in string.hexdigits:
                return
        event.Skip()
        return

if __name__ == '__main__':
    
    DECIMAL_DIGITS = 1
    HEX_DIGITS = 2
    LETTERS = 3

    app = wx.PySimpleApp()
    
    text = wx.TextEntryDialog(None, 'give me any number', caption='Title')
    txtCtrl = text.FindWindowById(3000)
    txtCtrl.Validator = CharValidator(DECIMAL_DIGITS)
    text.ShowModal()
    
    app.MainLoop()
    
    text.Destroy()
    app.Destroy()

Ur wrote:

Robin Dunn <robin <at> alldunn.com> writes:

David A. Barrett wrote:

Is there any way to add a validator to a wx.TextEntryDialog?
I tried using SetValidator() in the __init__ of a class inheriting
from wx.TextEntryDialog, but my Validate() method didn't seem
to get called on the OK press. I'll contrive and post a code
example is the answer to my question should be "yes."

You need to attach the validator to the text ctrl. It's not documented but it looks like it is always created with an ID of 3000, so you can get a reference to the textctrl with:

  txtctrl = dlg.FindWindowById(3000)

I set my simple Validator for TextEntryDialog, but now is Ok-Button
functionless. What's wrong here?

Your Validate method never returns True.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn <robin <at> alldunn.com> writes:

Ur wrote:
> Robin Dunn <robin <at> alldunn.com> writes:
>
>> David A. Barrett wrote:
>>> Is there any way to add a validator to a wx.TextEntryDialog?
>>> I tried using SetValidator() in the __init__ of a class inheriting
>>> from wx.TextEntryDialog, but my Validate() method didn't seem
>>> to get called on the OK press. I'll contrive and post a code
>>> example is the answer to my question should be "yes."
>> You need to attach the validator to the text ctrl. It's not documented
>> but it looks like it is always created with an ID of 3000, so you can
>> get a reference to the textctrl with:
>>
>> txtctrl = dlg.FindWindowById(3000)
>>
>
>
> I set my simple Validator for TextEntryDialog, but now is Ok-Button
> functionless. What's wrong here?

Your Validate method never returns True.

Thank You Robin for spending time.

When someone need it - I have change Validate as follow:

def Validate(self, win):
        valid = True
        textCtrl = self.Window
        value = textCtrl.Value
        if self.flag == LETTERS:
            for x in value:
                if x not in string.letters:
                    valid = False
        elif self.flag == DECIMAL_DIGITS:
            for x in value:
                if x not in string.digits:
                    valid = False
        elif self.flag == HEX_DIGITS:
            for x in value:
                if x not in string.hexdigits:
                    valid = False
            
        return valid

and it's work fine :slight_smile:

Dne pondělí, 19. ledna 2009 10:37:43 UTC+1 Ur napsal(a):

Robin Dunn <robin alldunn.com> writes:

Ur wrote:

Robin Dunn <robin alldunn.com> writes:

David A. Barrett wrote:

Is there any way to add a validator to a wx.TextEntryDialog?
I tried using SetValidator() in the init of a class inheriting
from wx.TextEntryDialog, but my Validate() method didn’t seem
to get called on the OK press. I’ll contrive and post a code
example is the answer to my question should be “yes.”
You need to attach the validator to the text ctrl. It’s not documented
but it looks like it is always created with an ID of 3000, so you can
get a reference to the textctrl with:

    txtctrl = dlg.FindWindowById(3000)

I set my simple Validator for TextEntryDialog, but now is Ok-Button
functionless. What’s wrong here?

Your Validate method never returns True.

Thank You Robin for spending time.

When someone need it - I have change Validate as follow:

def Validate(self, win):
valid = True
textCtrl = self.Window
value = textCtrl.Value
if self.flag == LETTERS:
for x in value:
if x not in string.letters:
valid = False
elif self.flag == DECIMAL_DIGITS:
for x in value:
if x not in string.digits:
valid = False
elif self.flag == HEX_DIGITS:
for x in value:
if x not in string.hexdigits:
valid = False

    return valid

and it’s work fine :slight_smile:

Just for your information:

It seems that adding validator to wx.TextEntryDialog is solved here, but I would just like add that to get the actual text from the dialog, you must ask

textctrl.GetValue() # the widget you get from FindWindowById(3000)

and not

dlg.GetValue() # you get empty string (why?)

Perhaps it might save someone’s time.

Regards,

Anna

annakrat wrote:

Just for your information:
It seems that adding validator to wx.TextEntryDialog is solved here, but
I would just like add that to get the actual text from the dialog, you
must ask

textctrl.GetValue() # the widget you get from FindWindowById(3000)
and not
dlg.GetValue() # you get empty string (why?)

Because the dialog has not fetched the value from the textctrl yet.

···

--
Robin Dunn
Software Craftsman

agraeper@googlemail.com wrote:

when does the dialog fetch the value from textctrl ?

Probably when the dialog is closed.

it cannot be the only way knowing an internal id to get the text ?

It was not designed to be used this way, (with arbitrary validators, or to have the text fetched while the dialog is still active) so it should not be too surprising that it may do things in a way that is not as easy as it could be for these use cases. It wouldn't be hard to reimplement if you need different features.

···

--
Robin Dunn
Software Craftsman

i read anywhere that the ok-button triggers OnOk() ??? that calls the dialogs validate() and transferfromwindow(). with print ‘xxx’ in the validators transfer(from|to)window methods one can see that with the ok-button the validators transferfromwindow is called. maybe it should do something else, than simply returning true ?!

but if it is not registered at the dialog, only textctrl and validator know each other. so the validator that could get the content of textctrl, cannot set the dialogs value.

now i am wondering when using no validator, after ok the dialogs GetValue returns the textctrls current value, so is there a dummy-default-validator that does the transfer correct ? or why else in our situation the dialog does not get the current value ? does the dialog looks for a validator at textctrl and if there is one, than he is relying on it.

probably not as interesting the simple TextEntryDialog, but i will have to write lots of more complex dialogs next time, so i’d like to understand more deeply.

···

On Thursday, February 28, 2013 3:05:33 AM UTC+1, Robin Dunn wrote:

agra...@googlemail.com wrote:

when does the dialog fetch the value from textctrl ?

Probably when the dialog is closed.

it cannot be the only way knowing an internal id to get the text ?

It was not designed to be used this way, (with arbitrary validators, or
to have the text fetched while the dialog is still active) so it should
not be too surprising that it may do things in a way that is not as easy
as it could be for these use cases. It wouldn’t be hard to reimplement
if you need different features.


Robin Dunn

Software Craftsman

http://wxPython.org

Hi,

i read anywhere that the ok-button triggers OnOk() ??? that calls the dialogs validate() and transferfromwindow(). with print 'xxx' in the validators transfer(from|to)window methods one can see that with the ok-button the validators transferfromwindow is called. maybe it should do something else, than simply returning true ?!
but if it is not registered at the dialog, only textctrl and validator know each other. so the validator that could get the content of textctrl, cannot set the dialogs value.

now i am wondering when using no validator, after ok the dialogs GetValue returns the textctrls current value, so is there a dummy-default-validator that does the transfer correct ? or why else in our situation the dialog does not get the current value ? does the dialog looks for a validator at textctrl and if there is one, than he is relying on it.

probably not as interesting the simple TextEntryDialog, but i will have to write lots of more complex dialogs next time, so i'd like to understand more deeply.

I haven't followed this thread nor do I use TextEntryDialog, but I extensively use validators to transfer data from/to controls and the database.

InitDialog is called automatically on a dialog, but there is no reason not to call it manually to load data from e.g. the database to the controls on a dialog/panel/frame or other control container.

To get the data from the controls to the database you call TransferDataFromWindow.

You can see some code sample for this in the MediaLocker (https://bitbucket.org/driscollis/medialocker) sample project, e.g. "mlsrc.controllers.base_addedit.onAdd".

Another approach is shown in the wiki.
http://wiki.wxpython.org/Data-aware%20Controls%20with%20Validators%2C%20Note%201

Then there is also the doc (I most of the time use the Phoenix doc):
http://wxpython.org/Phoenix/docs/html/validator_overview.html#validator-overview

If you use validators and have multiple panels etc do not forget to set the extra style "WS_EX_VALIDATE_RECURSIVELY", mentioned in the above doc.

Werner

···

On 28/02/2013 16:15, agraeper@googlemail.com wrote: