Can I have my custom TextCtrl inherit from my custom Window?

I want to add common behavior to all my widgets, and am trying
to figure out the best way to do this. One option is multiple
inheritence, but I keep getting segfaults. Another option would
be to subclass wxWindow or wxObject, and have my TextCtrl,
Button, etc. inherit from my subclasses of wxWindow or
wxObject. Can I do this, and if so, how?

Thanks.

···

--
Paul

For whatever it is worth, I tried sub-classing wx. It seems
to work only for single inheritance from a wx class, but not
with multiple inheritance of a wx class and one or more other
classes.

This is wxPython 2.4.1.2 on Linux. It *may* be different on
other platforms.

/Jean Brouwers

Paul McNett wrote:

···

I want to add common behavior to all my widgets, and am trying to figure out the best way to do this. One option is multiple inheritence, but I keep getting segfaults. Another option would be to subclass wxWindow or wxObject, and have my TextCtrl, Button, etc. inherit from my subclasses of wxWindow or wxObject. Can I do this, and if so, how?

Thanks.

Paul McNett wrote:

I want to add common behavior to all my widgets, and am trying to figure out the best way to do this. One option is multiple inheritence, but I keep getting segfaults. Another option would be to subclass wxWindow or wxObject, and have my TextCtrl, Button, etc. inherit from my subclasses of wxWindow or wxObject. Can I do this, and if so, how?

Mutiple inheritance simply won't work if more than one of the classes are wx classes. There is nothing that can be done about that.

There are a couple other approaches that will work. Depending on your needs one or the other may be better for you.

1. If all the "add common behavior" you need to do is done in event handlers then you can derive a class from wxEvtHandler, hook events to its methods using the EVT_ binders just like normal, and then push a new instance of this class onto all your windows using PushEventHandler. The advantage here is that it does not require deriving a new class for every window type.

2. Use a Mix-in class that does not derive from wxWindow (or perhaps not from anything at all) but just expects that it will be combined with a class that does derive from wxWindow. That way it can do everything it needs to with self as if it was a Window (EVT binders, call methods, etc.) Then just derive a new class that mutiply inherits from wxWhatever and your mix-in, and the __init__ will just call the wxWhatever.__init__ and theen Mixin.__init__ as normal.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn writes:

2. Use a Mix-in class that does not derive from wxWindow (or
perhaps not from anything at all) but just expects that it
will be combined with a class that does derive from wxWindow.
That way it can do everything it needs to with self as if it
was a Window (EVT binders, call methods, etc.) Then just
derive a new class that mutiply inherits from wxWhatever and
your mix-in, and the __init__ will just call the
wxWhatever.__init__ and theen Mixin.__init__ as normal.

Hmm. I had actually tried this, but with Python's new-style
classes. It appears to only work with old-style classes.

# -- begin sample - this example works
import wx

class TestMixin:
    def __init__(self):
        print self.GetClassName()

class TestTextCtrl(wx.TextCtrl, TestMixin):
    def __init__(self, fraime):
        wx.TextCtrl.__init__(self, frame, wx.NewId())
        TestMixin.__init__(self)

if __name__ == "__main__":
        app = wx.PySimpleApp()
        frame = wx.Frame(None, -1, '')
        object = TestTextCtrl(frame)
        frame.Show(1)
        app.MainLoop()

# -- end sample

If I change line 3 to:
class TestMixin(object):

I get the following:
[pmcnett@sol classes]$ python testmixin.py
Traceback (most recent call last):
  File "testmixin.py", line 16, in ?
    object = TestTextCtrl(frame)
  File "testmixin.py", line 9, in __init__
    wx.TextCtrl.__init__(self, frame, wx.NewId())
  File "/usr/lib/python2.3/site-packages/wxPython/controls.py", line 805, in __init__
    self._setOORInfo(self)
  File "/usr/lib/python2.3/site-packages/wxPython/windows.py", line 60, in _setOORInfo
    val = windowsc.wxEvtHandler__setOORInfo(self, *_args, **_kwargs)
TypeError: Type error in argument 1 of wxEvtHandler__setOORInfo. Expected _wxEvtHandler_p.
[pmcnett@sol classes]$

Anyway, thanks Robin! I'll just use the old-style classes, and
I have everything I desired. Now, I finally understand the term
"mixin". <g>

···

--
Paul

Paul McNett wrote:

Robin Dunn writes:

2. Use a Mix-in class that does not derive from wxWindow (or
perhaps not from anything at all) but just expects that it
will be combined with a class that does derive from wxWindow.
That way it can do everything it needs to with self as if it
was a Window (EVT binders, call methods, etc.) Then just
derive a new class that mutiply inherits from wxWhatever and
your mix-in, and the __init__ will just call the
wxWhatever.__init__ and theen Mixin.__init__ as normal.

Hmm. I had actually tried this, but with Python's new-style classes. It appears to only work with old-style classes.

Yep, there is an issue with 2.4 and prior trying to make wx-derived classes be new-style classes, but it will work in 2.5. (In fact, all the wx Classes are new-style classes themselves.)

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!