HI,
I have several custom Validators (wxPyValidator children), they get called
and work. But, in a parent form if I create my own Validate() method
(representative example below) they are no longer called.
btw The effect I am after is to get in the containing window(wxPanel in this
case) a list of contrls that failed validation so that I can tell the user
what to fix.
thanks,
norm
class BaseForm(wxPanel, BaseCommon):
def Validate(self):
self._invalid_Ctrls = []
for col in self._cols2ctrls.keys():
ctrl = self._cols2ctrls[col]
wxLogDebug("validating [%s]"%ctrl.GetName())
#don't know what ctrl.Validate() does,
#but it doesn't call ctrl.GetValidator().Validate()
if not ctrl.Validate():
wxLogDebug("failed validation [%s]"%ctrl.GetName())
self._invalid_Ctrls.append(ctrl)
return (len(self._invalid_Ctrls) == 0)
···
#---------------------------------------------------------------------------
class base_Validator(wxPyValidator):
def __init__(self, dbi_desc_tuple):
"""
dbi_desc_tuple dbi 2.0 desc tuple (name, type_code,
display_size, internal_size, precision, scale, null_ok)
"""
wxPyValidator.__init__(self)
self.t = dbi_desc_tuple
EVT_CHAR(self, self.OnChar)
def OnChar(self, event):
key = event.KeyCode()
if key < WXK_SPACE or key == WXK_DELETE or key > 255:
event.Skip() #skip is return too
ctrl = self.GetWindow()
val = ctrl.GetValue()
#this garbage is to make the value what it will be so that we can
try and validate it
(s,e) = ctrl.GetSelection()
if s==e: #start selection_idx==end selection_idx there is no
selection!
val = val[:ctrl.GetInsertionPoint()] + chr(key) +
val[ctrl.GetInsertionPoint():]
else: #need to replace current selection
val = val[:s] + chr(key) + val[e:]
if self.Validate(event.GetEventObject(), val):
event.Skip()
elif not wxValidator_IsSilent():
wxBell()
class cur_numba_Validator(base_Validator):
"Cursor based validator"
def __init__(self, get_cursor_func, dbi_desc_tuple):
"""
get_cursor_func returns the cursor for given control
"""
base_Validator.__init__(self, dbi_desc_tuple)
self.cur_func = get_cursor_func
def Clone(self):
return cur_numba_Validator(self.cur_func, self.t)
def OnChar(self, event):
key = event.KeyCode()
if key == WXK_SPACE:
return
else:
base_Validator.OnChar(self, event)
def TransferToWindow(self):
try:
ctrl = self.GetWindow()
value = self.cur_func()[ctrl.columnname]
(value))
if value == None:
ctrl.SetValue('')
else:
ctrl.SetValue( ("%%.%if" % self.t[5]) % float(value))
except:
wxLogException()
def TransferFromWindow(self):
try:
ctrl = self.GetWindow()
value = ctrl.GetValue().strip()
if value in ('', None):
self.cur_func()[ctrl.columnname] = None
elif self.t[5] > 0: #if precision is > 0 we reckon its a float
type field
self.cur_func()[ctrl.columnname] = float(value)
else:
self.cur_func()[ctrl.columnname] = int(value)
except:
wxLogException()
pass
def Validate(self, win, value=None):
ctrl = self.GetWindow()
if not value:
value = ctrl.GetValue()
if value in ('', None):
if self.t[6]:
return true
else:
wxLogDebug("%s null not ok" % (ctrl.GetName()) )
return false
if len(value) > self.t[3]:
return false
#check precession I have no idea why minus 2 instead of minus 1
if value.find('.') > 0 and (len(value)-2)-value.find('.') >=
self.t[5]:
self.t[5]))
return false
try:
if self.t[5] > 0:
#if precision is > 0 we reckon its a float type field else
an int
float(value)
else:
int(value)
return true
except ValueError:
return false