Eric Ries wrote:
Besides refactoring the masked controls, or making your own derived
versions of them[1] to allow them to be used with the subclass factory...
[1] Since the masked controls are composed with mixin classes (at least
in the 2.5.2 version I am looking at right now) this may not be as hard
as it sounds...I'd be interested in learning how to do this, as I think subclassing is a
very cool approach to this problem, since it allows the XRC editor to do a
reasonable job even though it doesn't know about the subclass. Is there a
sample or any documentation that might be helpful for me to look at? Is
there an example of a class that has been successfully refactored to make
this work?I tried refactoring the ColourSelect widget some time ago, but was unable to
make it work. Maybe if I get the hang of it I can refactor a few of the
widgets in wx.lib and submit them, if that would be useful.
Here is a basic recipie just off the top of my head. Assuming that the class you are working on is called D and it is derived from some built-in wx class called wx.B:
1. Move everything currently in in D.__init__ except the call to wx.B.__init__ into some other method, say _PostInit or something like that. If you need to pass extra args to _PostInit then be sure that they can be given suitable default values because when you use it in the XRC version you won't be able to pass any args.
2. Add a call to the _PostInit method from D.__init__.
3. Make a new class in the same module called PreD, or maybe XrcD or something that derives from D.
4. PreD.__init__ will need to take no extra args, and instead of calling D.__init__ you will need to call the "Pre" version of the wx class, like this:
class PreD(D):
def __init__(self):
pre = wx.PreB()
self.PostCreate(pre)
Then when an instance of this class is created, the C++ instance is also created, but the UI object will not be created until the Create() method is called, either explicitly from the programmer's code, or implicitly via XRC or something similar.
5. Add a handler for the EVT_WINDOW_CREATE event that calls the _PostInit method from step 1:
# this goes in the __init__ above
self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)
def OnCreate(self, evt):
self._PostInit()
Now when Create() is called the event will be sent and the rest of what used to be in __init__ will be executed and the control should be ready to use.
···
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!