From: Liam C. <cy...@gm...> - 2005-02-26 12:45:49
|
Kia ora, I'm playing around with text fields, and I'm trying to control what a user can type. So, I've used the following - def on_TextField1_keyPress(self, event): print 'foo' to test my theory. Now, I can press a key, and 'foo' will be printed to my console all day long, but the text isn't entered in the text field, so obviously I've overridden the default key press behaviour. My problem is, I can't find the default key press behaviour for a text field widget. I've looked in model.py, event.py, and widget.py, and if it's there, I've missed it. (which is highly likely, I ran out of coffee yesterday.) Is anyone able to point me at the right module? It would be much appreciated. Regards, Liam Clarke -- 'There is only one basic human right, and that is to do as you damn well please. And with it comes the only basic human duty, to take the consequences. |
From: Kevin A. <al...@se...> - 2005-02-26 16:05:50
|
On Feb 26, 2005, at 4:45 AM, Liam Clarke wrote: > Kia ora, > > I'm playing around with text fields, and I'm trying to control what a > user can type. > So, I've used the following - > > def on_TextField1_keyPress(self, event): > print 'foo' > > to test my theory. Now, I can press a key, and 'foo' will be printed > to my console all day long, but the text isn't entered in the text > field, so obviously I've overridden the default key press behaviour. > > My problem is, I can't find the default key press behaviour for a > text field widget. > I've looked in model.py, event.py, and widget.py, and if it's there, > I've missed it. (which is highly likely, I ran out of coffee > yesterday.) > > Is anyone able to point me at the right module? > > It would be much appreciated. > > Regards, > > Liam Clarke > -- > 'There is only one basic human right, and that is to do as you damn > well please. > And with it comes the only basic human duty, to take the consequences. > If you want the text to appear you need to add event.skip() on the line after your print statement. There are number of samples and tools that use keyDown, keyUp, and keyPress handlers, so you the findfiles tool to search for more examples that look at the keyCode... ka |
From: Brian D. <deb...@ho...> - 2005-02-28 13:36:39
|
Hi there, I was working on my text length limited widget, also I worked on a text field that only accepts numbers, and this is my code, hope it helps. def on_initialize(self, event): self.type = True def on_txtText_keyPress(self, event): keyCode = event.keyCode if keyCode in range(48,58) or keyCode in [8,316,317,318,319,127,314,315]: event.Skip() def on_txtText_keyPress(self, event): keyCode = event.keyCode if len(self.components.txtText.text) == 10: if keyCode in [8,316,317,318,319,127,314,315]: self.type = True else: self.type = False else: self.type = True if self.type: event.Skip() else: self.type = True Any suggestions or ideas on how to optmize this code, specially the text leght validation, are more than welcome. Regards, Brian _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Brian D. <deb...@ho...> - 2005-02-28 13:37:07
|
Hi there, I was working on my text length limited widget, also I worked on a text field that only accepts numbers, and this is my code, hope it helps. def on_initialize(self, event): self.type = True def on_txtText_keyPress(self, event): keyCode = event.keyCode if keyCode in range(48,58) or keyCode in [8,316,317,318,319,127,314,315]: event.Skip() def on_txtText_keyPress(self, event): keyCode = event.keyCode if len(self.components.txtText.text) == 10: if keyCode in [8,316,317,318,319,127,314,315]: self.type = True else: self.type = False else: self.type = True if self.type: event.Skip() else: self.type = True Any suggestions or ideas on how to optmize this code, specially the text leght validation, are more than welcome. Regards, Brian _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Alex T. <al...@tw...> - 2005-02-28 14:25:55
|
Brian Debuire wrote: > Hi there, > > I was working on my text length limited widget, also I worked on a > text field that only accepts numbers, and this is my code, hope it helps. > > > def on_initialize(self, event): > self.type = True Unnecessary (at least in the code shown here) - every path through on_txtText_keyPress sets it before using it. Is it used elsewhere ? > > def on_txtText_keyPress(self, event): > keyCode = event.keyCode > if len(self.components.txtText.text) == 10: > if keyCode in [8,316,317,318,319,127,314,315]: > self.type = True > else: > self.type = False > else: > self.type = True > if self.type: > event.Skip() > else: > self.type = True > > > Any suggestions or ideas on how to optmize this code, specially the > text leght validation, are more than welcome. I may be missing some subtlety - but why not simply > def on_txtText_keyPress(self, event): > if len(self.components.txtText.text) < 10 or event.keyCode in > [8,316,317,318,319,127,314,315]: > event.Skip() btw - I don't think this will be significantly more efficient - but I find it easier to read -- Alex Tweedly http://www.tweedly.net -- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.300 / Virus Database: 266.5.1 - Release Date: 27/02/2005 |
From: Brian D. <deb...@ho...> - 2005-02-28 14:31:07
|
Hi there, Thanks Alex the code works fine and it really is easier to read. But requesting more help how do I mix the text length and the numbers only validation??? Thanks in advance. Brian _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Alex T. <al...@tw...> - 2005-02-28 14:59:58
|
Brian Debuire wrote: > Hi there, > > Thanks Alex the code works fine and it really is easier to read. > > But requesting more help how do I mix the text length and the numbers > only validation??? > def on_txtText_keyPress(self, event): if ( len(self.components.txtText.text) < 10 and event.keyCode in [45-58] ) or \ event.keyCode in [8,316,317,318,319,127,314,315]: event.Skip() Not quite so readable unfortunately. -- Alex Tweedly http://www.tweedly.net -- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.300 / Virus Database: 266.5.1 - Release Date: 27/02/2005 |
From: Brian D. <deb...@ho...> - 2005-02-28 14:32:02
|
Hi there, Thanks Alex the code works fine and it really is easier to read. But requesting more help how do I mix the text length and the numbers only validation??? Thanks in advance. Brian _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Aaron H. <arc...@gm...> - 2005-02-28 15:23:11
|
On Mon, 2005-02-28 at 14:25 +0000, Alex Tweedly wrote: > > def on_txtText_keyPress(self, event): > > if len(self.components.txtText.text) < 10 or event.keyCode > in=20 > > [8,316,317,318,319,127,314,315]: > > event.Skip() Here's what I do: 1. create a class module to handle keypress tests 2. in it, define some lists and functions like this: __digit_keys__ =3D [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, wx.WXK_NUMPAD8, wx.WXK_NUMPAD9] __money_keys__ =3D [36, 44, 46] __ctrl_keys__ =3D [wx.WXK_NUMLOCK, wx.WXK_CAPITAL, wx.WXK_SCROLL] __nav_keys__ =3D [wx.WXK_DELETE, wx.WXK_BACK, wx.WXK_TAB, wx.WXK_RETURN, wx.WXK_LEFT, wx.WXK_RIGHT] __date_keys__ =3D [wx.WXK_DIVIDE, wx.WXK_SUBTRACT, 45, 47] __zip_keys__ =3D [wx.WXK_SUBTRACT, 45] __phone_keys__ =3D [32, 40, 41, 45, 120, wx.WXK_SUBTRACT] __valid_date_keycodes__ =3D __digit_keys__ + __date_keys__ + __ctrl_keys__ __valid_money_keycodes__ =3D __digit_keys__ + __money_keys__ + __ctrl_keys__ __valid_zipcode_keycodes__ =3D __digit_keys__ + __zip_keys__ + __ctrl_keys__ __valid_phone_keycodes__ =3D __digit_keys__ + __phone_keys__ + __ctrl_keys__ __valid_integer_keycodes__ =3D __digit_keys__ + __ctrl_keys__ def isNavKey(self, keyCode): """ Tells whether a key pressed was a navigational key (like tab, delete, etc.) """ return keyCode in self.__nav_keys__ def validkey_date(self, keyCode): return self.isNavKey(keyCode) or keyCode in self.__valid_date_keycodes__ def validkey_zip(self, keyCode): return self.isNavKey(keyCode) or keyCode in self.__valid_zipcode_keycodes__ def validkey_money(self, keyCode): return self.isNavKey(keyCode) or keyCode in self.__valid_money_keycodes__ def validkey_phone(self, keyCode): return self.isNavKey(keyCode) or keyCode in self.__valid_phone_keycodes__ def validkey_integer(self, keyCode): return self.isNavKey(keyCode) or keyCode in self.__valid_integer_keycodes__ 3. in my app's init attribute/method: import keyCodeTests kct =3D keyCodeTests.keyCodeTests() 4. in keyPress events, something like this: def on_MyIntegerField_keyPress(self, event): if kct.isNavKey(event.keyCode) or (kct.validkey_integer (event.keyCode) and len(event.target.text) < self.__MyIntegerField_MAXLEN__): event.skip() FWIW, you should probably set things like max acceptable field length, max acceptable values, etc., for your fields in a config file and then write code to read the config first thing (during init). That way you easily change stuff without having to re-write code. Hope this helps. -Aaron |
From: Liam C. <cy...@gm...> - 2005-02-28 21:05:28
|
Sheesh. What I've come up with is this - store each textfield/area's restrictions on init - from Pythoncard import model import re def on_initialize(self, event): self.limits = {'text1':{'length':20, 'phone':True}} #complete for each limited widget self.PhoneRE = re.compile('[0-9\(\)\-\\b]') def on_keyPress(self, event): eventSource = event.target sourceClass = str(event.target.__class__) if not (sourceClass.endswith(" Textfield>\' ") or sourceClass.endswith(" Textarea>\' "): #Could just check hasattr('editable') and then if editable is set to Treu event.skip() return length = self.limits[eventSource.name]['length'] isPhoneNumber = self.limits[eventSource.name]['phone'] if len(eventSource.text) < length or keyCode == 8 #(backspace): If isPhoneNumber: if not self.PhoneRE.search(chr(event.keyCode)): return event.skip() return This is rough code, but basically it checks the length to make sure the new char won't exceed it, (unless it's backspace, I'll probably have to check for enter/tab as well.) And then it runs it through a RE if needed, in this case just a simple one [0-9\(\)\-\\b] which sould limit valid keystrokes to 0123456789()- and backspace Which should be enough to write a phone number. So, I just plan to write a minimalist child window with this method and subclass whenever I need to validate text. That said, I was recently made aware of the fact that I have, in effect, just re-invented the wheel, on account of wxPython's validators. But, they look scary in the demo, so I'm happy. But thanks for the info, I like the __nav_keys__ stuff. Regards, Liam Clarke On Mon, 28 Feb 2005 10:25:21 -0500, Aaron Howard <arc...@gm...> wrote: > On Mon, 2005-02-28 at 14:25 +0000, Alex Tweedly wrote: > > > def on_txtText_keyPress(self, event): > > > if len(self.components.txtText.text) < 10 or event.keyCode > > in > > > [8,316,317,318,319,127,314,315]: > > > event.Skip() > > Here's what I do: > > 1. create a class module to handle keypress tests > 2. in it, define some lists and functions like this: > > __digit_keys__ = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, > wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, > wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, > wx.WXK_NUMPAD8, wx.WXK_NUMPAD9] > > __money_keys__ = [36, 44, 46] > > __ctrl_keys__ = [wx.WXK_NUMLOCK, wx.WXK_CAPITAL, wx.WXK_SCROLL] > > __nav_keys__ = [wx.WXK_DELETE, wx.WXK_BACK, wx.WXK_TAB, > wx.WXK_RETURN, wx.WXK_LEFT, wx.WXK_RIGHT] > > __date_keys__ = [wx.WXK_DIVIDE, wx.WXK_SUBTRACT, 45, 47] > __zip_keys__ = [wx.WXK_SUBTRACT, 45] > __phone_keys__ = [32, 40, 41, 45, 120, wx.WXK_SUBTRACT] > > __valid_date_keycodes__ = __digit_keys__ + __date_keys__ + > __ctrl_keys__ > __valid_money_keycodes__ = __digit_keys__ + __money_keys__ + > __ctrl_keys__ > __valid_zipcode_keycodes__ = __digit_keys__ + __zip_keys__ + > __ctrl_keys__ > __valid_phone_keycodes__ = __digit_keys__ + __phone_keys__ + > __ctrl_keys__ > __valid_integer_keycodes__ = __digit_keys__ + __ctrl_keys__ > > def isNavKey(self, keyCode): > """ Tells whether a key pressed was a navigational key (like > tab, delete, etc.) """ > return keyCode in self.__nav_keys__ > > def validkey_date(self, keyCode): > return self.isNavKey(keyCode) or keyCode in > self.__valid_date_keycodes__ > > def validkey_zip(self, keyCode): > return self.isNavKey(keyCode) or keyCode in > self.__valid_zipcode_keycodes__ > > def validkey_money(self, keyCode): > return self.isNavKey(keyCode) or keyCode in > self.__valid_money_keycodes__ > > def validkey_phone(self, keyCode): > return self.isNavKey(keyCode) or keyCode in > self.__valid_phone_keycodes__ > > def validkey_integer(self, keyCode): > return self.isNavKey(keyCode) or keyCode in > self.__valid_integer_keycodes__ > > 3. in my app's init attribute/method: > import keyCodeTests > kct = keyCodeTests.keyCodeTests() > > 4. in keyPress events, something like this: > > def on_MyIntegerField_keyPress(self, event): > if kct.isNavKey(event.keyCode) or (kct.validkey_integer > (event.keyCode) and len(event.target.text) < > self.__MyIntegerField_MAXLEN__): > event.skip() > > FWIW, you should probably set things like max acceptable field length, > max acceptable values, etc., for your fields in a config file and then > write code to read the config first thing (during init). That way you > easily change stuff without having to re-write code. > > Hope this helps. > > -Aaron > > > -- 'There is only one basic human right, and that is to do as you damn well please. And with it comes the only basic human duty, to take the consequences. |