Thanks all
below the solution which I implemented.
It consists of 2 parts:
Firstly an xml handler which builds by default all 3 States CheckBox.
Secondly a validator who according to specified constraints and linked to a CheckBox, limits it to 2 states or 3 states.
class ThreeStateCheckBoxXmlHandler(xrc.XmlResourceHandler):
def __init__(self):
xrc.XmlResourceHandler.__init__(self)
# Specify the styles recognized by objects of this type
self.AddStyle("wxCHK_2STATE", wx.CHK_2STATE);
self.AddStyle("wxCHK_3STATE", wx.CHK_3STATE);
self.AddStyle("wxCHK_ALLOW_3RD_STATE_FOR_USER", wx.CHK_ALLOW_3RD_STATE_FOR_USER);
self.AddWindowStyles();
# This method and the next one are required for XmlResourceHandlers
def CanHandle(self, node):
return self.IsOfClass(node, "wxCheckBox")
def DoCreateResource(self):
# the instance may already have been created, check for it
chkBox = self.GetInstance()
if chkBox is None:
# if not, then create the instance (but not the window)
chkBox = wx.PreCheckBox()
# Now call the CheckBox's Create method to actually create the window
chkBox = wx.CheckBox(self.GetParentAsWindow(),
id=self.GetID(),
label=self.GetParamValue("label"),
pos=self.GetPosition(),
size=self.GetSize(),
style=self.GetStyle("style", wx.CHK_3STATE)|self.GetStyle("style",wx.CHK_ALLOW_3RD_STATE_FOR_USER),
name=self.GetName()
)
self.SetupWindow(chkBox)
return chkBox
class _BaseObjectValidator(wx.PyValidator):
""" This validator is the base class for all validator
"""
def __init__(self,**kwargs):
self.__dict__.update(kwargs)
self.__kwargs = kwargs
wx.PyValidator.__init__(self)
def Clone(self):
""" Standard cloner.
Note that every validator must implement the Clone() method.
"""
return self.__class__(**self.__kwargs)
class BolleanObjectValidator(_BaseObjectValidator):
""" This validator is used to ensure that the user has entered something
into the dialog's checkbox field valid according to the constraints
specified for boolean element.
"""
def __init__(self,
value,
descr,
defaultValue=None,
mandatory=False):
if defaultValue is None:
defaultValue=False
_BaseObjectValidator.__init__(self,
value=value,
descr=descr,
defaultValue=defaultValue,
mandatory=mandatory)
self.Bind(wx.EVT_CHECKBOX, self._OnCheck)
def _OnCheck(self,evt):
if self.mandatory and \
evt.GetInt() == wx.CHK_UNDETERMINED:
chkBox = evt.GetEventObject()
self._toGUI(not evt.IsChecked())
evt.Skip()
def _fromGUI(self):
chkBox = self.GetWindow()
if chkBox.Is3State():
state = chkBox.Get3StateValue()
else:
state = chkBox.GetValue()
if state == wx.CHK_UNCHECKED:
return None
if state == wx.CHK_CHECKED:
return True
return False
def _toGUI(self,value):
chkBox = self.GetWindow()
if value is None:
if self.mandatory or not chkBox.Is3State():
self._toGUI(self.defaultValue)
return
state = wx.CHK_UNDETERMINED
elif value:
state = wx.CHK_CHECKED
else:
state = wx.CHK_UNCHECKED
if chkBox.Is3State():
chkBox.Set3StateValue(state)
else:
chkBox.SetValue(state)
chkBox.Refresh()
def Validate(self, win):
""" Validate the contents of the given text control.
"""
chkBox = self.GetWindow()
value = self._fromGUI()
valid = True
if self.mandatory and not value:
wx.MessageBox(u"Vous devez spécifier une valeur pour %s"% \
self.descr,u"Erreur")
valid = False
if not valid:
chkBox.SetBackgroundColour(_invalidBackgroundColor)
chkBox.SetFocus()
chkBox.Refresh()
return False
else:
chkBox.SetBackgroundColour(
wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
chkBox.Refresh()
return True
def TransferFromWindow(self):
""" Transfer data from window to validator.
The default implementation returns False, indicating that an error
occurred. We simply return True, as we don't do any data transfer.
If minLen is > 1, set backgournd color to color defined for
mandatory data
"""
self.value = self._fromGUI()
return True
def TransferToWindow(self):
""" Transfer data from validator to window.
The default implementation returns False, indicating that an error
occurred. We simply return True, as we don't do any data transfer.
"""
self._toGUI(self.value)
if self.mandatory and self.IsEnable():
self.GetWindow().SetBackgroundColour(_mandatoryBackgroundColor)
self.GetWindow().Refresh()
return True # Prevent wxDialog from complaining.
···
-----Original Message-----
From: Uwe C. Schroeder [mailto:uwe@oss4u.com]
Sent: mercredi 1 septembre 2004 19:09
To: wxPython-users@lists.wxwidgets.org
Subject: Re: [wxPython-users] 3State CheckBox and XRC how can I do
(2.5.2.8u)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Wednesday 01 September 2004 02:36 am, Mignon Laurent wrote:
Is It possible to specified a 3State Checkbox with XRC resources?
Since its'nt possible to specified style directly in the resource file
edited by Xrced, I'have tried to create my own subclass to add style to
control but that don't work.class XRC3StateCheckBoxCtrl(wx.CheckBox):
"""
This allows us to use XRC subclassing for CheckBox.
"""
_firstEventType = wx.EVT_SIZEdef __init__(self):
pre = wx.PreCheckBox()
self.PostCreate(pre)
self.Bind(self._firstEventType, self.OnCreate)def OnCreate(self, evt):
self.SetWindowStyle(wx.CHK_3STATE|wx.CHK_ALLOW_3RD_STATE_FOR_USER)
self.Refresh()
self.Unbind(self._firstEventType)What's the solution?
Since there's currently no support for the extra styles, you can write your
own xml handler and register it with xrc. Read the docs on custom xml
handlers, it's actually quite easy (and you can copy a skeleton from the
demo). This would allow you do use your subclassed version to create the
control.
UC
- --
Open Source Solutions 4U, LLC 2570 Fleetwood Drive
Phone: +1 650 872 2425 San Bruno, CA 94066
Cell: +1 650 302 2405 United States
Fax: +1 650 872 2417
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org