Hi,
I'm making some validators for the program I'm working on and got stuck
with this one.
The problem is that when RangeValidator is instanciated I get a
wxPyDeadObjectError exception. I never got anything like this before and
don't know how to avoid it but everything seems to work correctly anyway.
I'm using Python 2.2.2 and wxPython 2.4.0.3 on Win2000.
TIA,
Javier
PS: I never used wxCallAfter before either and found nothing in the docs
for it so I was also wondering if I'm using it correctly.
--- Exception --------------------------------------------------
Traceback (most recent call last):
File "C:\Python22\lib\site-packages\wxPython\wx.py", line 1645, in
<lambda>
lambda event: apply(event.callable, event.args, event.kw) )
File "paquetes\stock\mantenimiento\producto.py", line 528, in __call__
ctrl = self.validator.GetWindow()
File "C:\Python22\lib\site-packages\wxPython\wx.py", line 1678, in
__getattr__
raise wxPyDeadObjectError( self.attrStr % self._name )
wxPython.wx.wxPyDeadObjectError: The C++ part of the RangeValidator
object has been deleted, attribute access no longer allowed.
···
-----------------------------------------------------------------
--- Code --------------------------------------------------------
# This class only allows allows digits to be entered and if the
# value is invalid, sets the foreground color to 'color_mal'.
class RangeValidator(wxPyValidator):
"""RangeValidator(min=0, max=None, extras=None, color_bien=wxBLACK,
color_mal=wxRED) -> wxPyValidator
Este validator se especializa en rangos de números y permite filtrar
y avisar gráficamente si se está fuera de el rango dado y no en los
extras o en el rango y en los extras.
Si el valor del control que se está validando no se encuentra entre
el rango dado, el texto de este se pone rojo.
"""
def __init__(self, min=0, max=None, extras=None, color_bien=wxBLACK,
color_mal=wxRED):
wxPyValidator.__init__(self)
self.min = 0
self.max = max
self.color_bien = color_bien
self.color_mal = color_mal
if extras is None:
extras = []
self.extras = extras
import string
self.digits = string.digits
class aux:
def __init__(self, validator):
self.validator = validator
def __call__(self):
ctrl = self.validator.GetWindow()
EVT_TEXT(ctrl, ctrl.GetId(), self.validator.OnText)
wxCallAfter(aux(self))
EVT_CHAR(self, self.OnChar)
def Clone(self):
return RangeValidator(self.min, self.max, self.extras,
self.color_bien, self.color_mal)
def SetError(self, error):
if error:
newColor = self.color_mal
else:
newColor = self.color_bien
ctrl = self.GetWindow()
if newColor != ctrl.GetForegroundColour():
ctrl.SetForegroundColour(newColor)
ctrl.Refresh(False)
def OnChar(self, event):
key = event.KeyCode()
if key < WXK_SPACE or key == WXK_DELETE or key > 255 or \
chr(key) in self.digits:
event.Skip()
elif not wxValidator_IsSilent():
wxBell()
def OnText(self, event):
event.Skip()
print "OnText", dir(event)
t = event.GetEventObject().GetValue()
try:
n = long(t)
except ValueError, e:
self.SetError(t.strip() != '')
return
min = self.min
max = self.max
ex = self.extras
error = not ((min <= n and (max is None or n <= max) and n not
in ex) \
or ((min > n or max is not None and n > max) and n in ex))
self.SetError(error)