wxPython, C++ wxEvtHandler

hey all,

I am sort of new to wxPython and this list. I have a written a wxWindows application in C++ and have added wxPython support lately. What I'd like to do is to be able to add wxPython event handlers to the main frame (or other components, but mainly the main frame) but it does not seem to work. Here's how I tried to do it:
I create a Python extension that gives the Python code access to the c++-created wxFrame, then I call PushEventHandler() on that object with my python-created wxEvtHandler -derived object. But the python methods are not called. This way of doing works fine though if I use it on Python-created wxFrames (and in C++ only stuff as well).

How would can I manage to register a wxPython-created wxEvtHandler -derived class to a C++ -created class (PushEventHandler does not seem to work?). Or in general any suggested way of registering python event handlers with C++ code?

Help would be very appreciated. Thank you.

- Lorant Toth

Lorant Toth wrote:

hey all,

I am sort of new to wxPython and this list. I have a written a wxWindows application in C++ and have added wxPython support lately. What I'd like to do is to be able to add wxPython event handlers to the main frame (or other components, but mainly the main frame) but it does not seem to work. Here's how I tried to do it:
I create a Python extension that gives the Python code access to the c++-created wxFrame,

You shouldn't need a whole extension module just for this (although it doesn't hurt.) You don't provide very many details so I'll just give a general answer. I assume that you follow the general principles shown in the embedded sample. If not, you should.

The first thing you need is to put a Python wxFrame proxy around your C++ object the same way that wxPython does it. Something like this in either your extension or your application code:

  wxPyBeginBlockThreads();
  PyObject* pyFrame = wxPyMake_wxObject(theFrame, true);
  wxPyEndBlockThreads();

You can then make pyFrame available to Python code by stuffing it in your extension module's namespace, or just putting it in a dictionary to be used as the namespace for code you execute with PyRun_String. Once that is done then any Python code that you run that uses pyFrame should work fine.

···

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

Thank you very much for the answer. Already thought there would be no reply for now (b/c my question was not very detailed - and I understand other people are busy too and this is all voluntary work - but same goes as for wxWin: great support :wink:
So I sat down the last two days and figured out the cause. After lots of debugging I figured that the XRC lib's XRCID() macro gives different identifiers when called from C++ and wxPython (6041 from C++ and 6000 from Python) so no wonder the event handlers (for menu items or buttons are not called when they should be). I have two guesses:
- Either I link in the XRC lib twice
- or there are two sets of XRC globals (== linking twice?)

More info: Testing is done on windows. The app is using wx, XRC, STC and FL, only wx and XRC from Python for now.

My first idea was that maybe wxPython did not properly work when evt-hooked to C++ code but as I figured by now it is a fully compatible implementation, even event-thunking. Hope I can work out the rest myself now :slight_smile:

Thanks,

Lorant

Robin Dunn wrote:

···

Lorant Toth wrote:

hey all,

I am sort of new to wxPython and this list. I have a written a wxWindows application in C++ and have added wxPython support lately. What I'd like to do is to be able to add wxPython event handlers to the main frame (or other components, but mainly the main frame) but it does not seem to work. Here's how I tried to do it:
I create a Python extension that gives the Python code access to the c++-created wxFrame,

You shouldn't need a whole extension module just for this (although it doesn't hurt.) You don't provide very many details so I'll just give a general answer. I assume that you follow the general principles shown in the embedded sample. If not, you should.

The first thing you need is to put a Python wxFrame proxy around your C++ object the same way that wxPython does it. Something like this in either your extension or your application code:

    wxPyBeginBlockThreads();
    PyObject* pyFrame = wxPyMake_wxObject(theFrame, true);
    wxPyEndBlockThreads();

You can then make pyFrame available to Python code by stuffing it in your extension module's namespace, or just putting it in a dictionary to be used as the namespace for code you execute with PyRun_String. Once that is done then any Python code that you run that uses pyFrame should work fine.

Lorant Toth wrote:

Thank you very much for the answer. Already thought there would be no reply for now (b/c my question was not very detailed - and I understand other people are busy too and this is all voluntary work - but same goes as for wxWin: great support :wink:
So I sat down the last two days and figured out the cause. After lots of debugging I figured that the XRC lib's XRCID() macro gives different identifiers when called from C++ and wxPython (6041 from C++ and 6000 from Python) so no wonder the event handlers (for menu items or buttons are not called when they should be). I have two guesses:
- Either I link in the XRC lib twice
- or there are two sets of XRC globals (== linking twice?)

Yes, this is probably the problem. For reasons I don't completely remember wxPython 2.4 and prior compiled it's own copy of the wx contrib libs and statically links their object modules into the extensions. So there is a copy of the XRC lib in xrcc.pyd and a copy that your app is using.

I've already changed this for 2.5, but I'm not sure what to suggest as a workaround for 2.4 other than tweaking setup.py and building your own copy of wxPython that uses a xrc DLL...

···

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

Robin Dunn wrote:

Lorant Toth wrote:

Thank you very much for the answer. Already thought there would be no reply for now (b/c my question was not very detailed - and I understand other people are busy too and this is all voluntary work - but same goes as for wxWin: great support :wink:
So I sat down the last two days and figured out the cause. After lots of debugging I figured that the XRC lib's XRCID() macro gives different identifiers when called from C++ and wxPython (6041 from C++ and 6000 from Python) so no wonder the event handlers (for menu items or buttons are not called when they should be). I have two guesses:
- Either I link in the XRC lib twice
- or there are two sets of XRC globals (== linking twice?)

Yes, this is probably the problem. For reasons I don't completely remember wxPython 2.4 and prior compiled it's own copy of the wx contrib libs and statically links their object modules into the extensions. So there is a copy of the XRC lib in xrcc.pyd and a copy that your app is using.

I've already changed this for 2.5, but I'm not sure what to suggest as a workaround for 2.4 other than tweaking setup.py and building your own copy of wxPython that uses a xrc DLL...

Thanks for these hints too, I was trying to tweak the setup.py file but for some reason this would not work, even taking out all .cpp files but the xrc.cpp and linking against wxxrcdll.lib seemed to create the whole thing...
B/c the main problem (for now at least) is that the two return different XRCID()'s I'll just write a wrapper function that calls the App's XRCID(). Maybe I'll also take a look at the 2.5 setup.py to see what I did wrong.

Once again, thanks for the great support :wink:

- Lorant