C++ extension, button does not display

I tried to learn how to make a C++ extension for wxPython.
My frist aim was to make wxPython byndings for the simple FooButton class presented in http://wiki.wxpython.org/C%2B%2BExtensions.
Since that tutorial seems to be outdated, after a lot of searches on the wxPython-users group I finally managed to compile the extension.
A small wxPython application uses the FooButton extension without any errors - but the button does not appear!

Later I added a diagnostic print statement in the C++ constructor of FooButton and indeed I get the correct output in the terminal (but the
FooButton does not appear in the wxPython application. If I substitute an ordinary wx.Button for FooButton the wx.Button appears wthout any problem.

I used wxPython 2.9.4.0 and build swig 1.3.29 with the appropriate patch applied.

Here is the FooButton.i interface file:

%module foobutton

%{
#include “wx/wx.h”
#include “wx/wxPython/wxPython.h”
#include “wx/wxPython/pyclasses.h”
class wxPyTreeCtrl;

#include “foobutton.h”
%}

class wxPyTreeCtrl;

%import typemaps.i
%import my_typemaps.i

%import core.i
%import controls.i

%pythoncode { import wx }
%pythoncode { docfilter = wx._core.__DocFilter(globals()) }

class FooButton : public wxButton
{
public:
FooButton(wxWindow *parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = “foobutton”);
~FooButton();
private:
DECLARE_CLASS(FooButton);
};

I use the following Makefile:

WX_CXXFLAGS = -fpic -I/home/romuald/software/wxPython-src-2.9.4.0/include -I/home/romuald/software/wxPython-src-2.9.4.0/wxPython/include -I/home/romuald/software/wxPython-src-2.9.4.0/bld/lib/wx/include/gtk2-unicode-2.9 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -DSWIG_TYPE_TABLE=_wxPython_table -pthread
WX_LIBS = -L/usr/local/lib -pthread -L/usr/lib/x86_64-linux-gnu -L/home/romuald/software/wxPython-src-2.9.4.0/bld/lib -lwx_gtk2u_core-2.9 -lwx_baseu-2.9 -lwx_gtk2u_aui-2.9 -lwxcode_gtk2_freechart-2.8
LIBS =

py: foobutton.o foobutton_wrap.o
g++ -shared foobutton.o foobutton_wrap.o $(WX_LIBS) $(LIBS) -o _foobutton.so

foobutton.o: foobutton.cpp
g++ -c -o $@ $(WX_CXXFLAGS) foobutton.cpp

foobutton_wrap.o: foobutton_wrap.cxx
g++ -c $(WX_CXXFLAGS) -I/usr/include/python2.7 foobutton_wrap.cxx

foobutton_wrap.cxx: foobutton.i
wxswig -c++ -python -Wall -nodefault -python -keyword -new_repr -modern -D__WXGTK__ -I/home/romuald/software/wxPython-src-2.9.4.0/wxPython/src foobutton.i

I would be grateful for any hint what I should change and what is the reason for the fact that the FooButton does not appear.

Just for completeness I am attaching all the relevant files: the C++ files: foobutton.cpp and foobutton.h, the SWIG interface file foobutton.i, the Makefile (with added txt extension so that I could attach it) and the python test script (adapted from some tutorial)

foobutton.i (800 Bytes)

foobutton.h (504 Bytes)

foobutton.cpp (528 Bytes)

test.py (889 Bytes)

Makefile.txt (1022 Bytes)

rmldj wrote:

Just for completeness I am attaching all the relevant files: the C++
files: foobutton.cpp and foobutton.h, the SWIG interface file
foobutton.i, the Makefile (with added txt extension so that I could
attach it) and the python test script (adapted from some tutorial)

Try adding the WIT and see if you can see anything odd about the properties of the FooButton vs the wx.Button there. http://wiki.wxpython.org/Widget_Inspection_Tool You can also interact with the object in the WIT's interactive interpreter to experiment with it. (Move, resize, show/hide, etc.)

···

--
Robin Dunn
Software Craftsman

Try adding the WIT and see if you can see anything odd about the
properties of the FooButton vs the wx.Button there.
http://wiki.wxpython.org/Widget_Inspection_Tool You can also interact
with the object in the WIT’s interactive interpreter to experiment with
it. (Move, resize, show/hide, etc.)

Thanks for the suggestion - I did that and indeed FooButton is not seen at all as a child of Panel.
The python code that I am using to add it is

class Example(wx.Frame):

def __init__(self, *args, **kw):
    super(Example, self).__init__(*args, **kw)
   
    self.InitUI()
   
def InitUI(self):  

    pnl = wx.Panel(self)
    cbtn = wx.Button(pnl, label='Quit', pos=(20, 20))

    cbtn.Bind(wx.EVT_BUTTON, self.OnClose)
    fbtn = FooButton(pnl, wx.ID_ANY,label='foo', pos=(20, 50))
    stdbtn = wx.Button(pnl, wx.ID_ANY, label='std', pos=(20, 70))

    self.SetSize((250, 200))
    self.SetTitle('wx.Button')
    self.Centre()
    self.Show(True)         

So perhaps something was wrong in the way I wrote the swig interface file?

···

On Wednesday, June 26, 2013 10:43:50 PM UTC+2, Robin Dunn wrote:

rmldj wrote:

    Try adding the WIT and see if you can see anything odd about the
    properties of the FooButton vs the wx.Button there.
    http://wiki.wxpython.org/Widget_Inspection_Tool
    <http://wiki.wxpython.org/Widget_Inspection_Tool&gt; You can also interact
    with the object in the WIT's interactive interpreter to experiment with
    it. (Move, resize, show/hide, etc.)

Thanks for the suggestion - I did that and indeed FooButton is not seen
at all as a child of Panel.

So perhaps something was wrong in the way I wrote the swig interface file?

Ok, I really should have seen this earlier, it's been a while since I spent a lot of time on Classic though. The issue is that by default instances of classes that have a destructor will be destroyed when the Python proxy object's ref count drops to zero. Since widget objects are owned by their parent window then we don't want that to happen, their destructions should instead be controlled by their parent. Since there wasn't a good way to do that in SWIG when wxPython was starting out I instead chose to just not let it see that there is a destructor in those classes.

So to fix your problem just comment out the ~FooButton line in your .i file.

···

On Wednesday, June 26, 2013 10:43:50 PM UTC+2, Robin Dunn wrote:

--
Robin Dunn
Software Craftsman

Thanks! Now it works and the button shows up.

One final question: when running the python code I get a message:

swig/python detected a memory leak of type ‘FooButton *’, no destructor found.
Is this just the default behaviour? Of course this seems not to have any ill effects on functionality so one should just live with it and ignore the message?
Once again many thanks for your help!

Just in case anyone would like to see the full working details, I wrote up the setup for compiling FooButton as wxPython extension in an answer to my question on stackoverflow:

http://stackoverflow.com/questions/17065114/how-to-use-a-contributed-c-wxwidget-in-wxpython