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. |