[PyKDE] embedding python widgets in C++ app
Phil Thompson
phil at riverbankcomputing.co.uk
Mon Jan 22 10:46:07 GMT 2007
On Monday 22 January 2007 9:21 am, Patrick Stinson wrote:
> oops, I think the title is backwards. I will send the author an email.
> I am trying to embed a python widget in a C++ application, where he is
> trying to access his C++ app code from his python code.
>
> I decided to manually import a module with a factory function, call
> that factory function from C++ and convert the python object to a
> QWidget * using sipConvertToInstance. After doing this, I have a few
> questions:
>
> What should the transfer object be as passed to sipConvertToInstance?
> I'm a little confused about the wording in the documentation, and
> sipTransferObj is automatically included if you are using this in a
> sip file.
It depends on what you are going to do with the C++ instance (when is the dtor
going to be called) and it's Python object (when is it going to be garbage
collected). Do you want the C++ instance to outlive the Python object?
> How are you supposed to statically link the PyQt libraries if you then
> lose the PyQt4 package, which initQtGui() expects to import QtCore
> from? initQtCore() works fine but initQtGui() fails looking for
> PyQt4.QtGui.
PyQt modules are modules - they are not libraries. You do not link against
them. You can configure them as builtin modules, just like any other module.
> Any comments on the following code?
>
> char nameBuf[2048];
> strcpy(nameBuf, moduleName);
> PyObject *module = PyImport_ImportModule(nameBuf);
> if(module)
> {
> PyObject *_create = PyObject_GetAttrString(module, "_create");
> if(_create)
> {
> if(PyCallable_Check(_create))
> {
> PyObject *sipPy = PyObject_Call(_create,
> Py_BuildValue("()"), NULL);
> if(sipPy)
> {
> int iserr = 0;
> QWidget *widget = reinterpret_cast<QWidget
> *>(sipConvertToInstance(sipPy, sipClass_QWidget, NULL, SIP\
> _NO_CONVERTORS, 0, &iserr));
> if(iserr == 0 && widget)
> {
> widget->show();
> qDebug("GOT WIDGET %p", widget);
> ret = widget;
> }
> else
> qWarning("could not sip => widget");
> }
> else
> qWarning("error in _create return (%p)", sipPy);
> }
> else
> qWarning("error \"_create\" is not callable");
> Py_DECREF(_create);
> }
> else
> qWarning("no attribute \"_create\"");
> }
> else
> qWarning("no module \"pktest\"");
Obviously you are leaking the sipPy and widget instances.
The above code has to be part of a SIP generated module that %Imports
PyQt4.QtGui. The SIP API can only be called from SIP generated modules.
Phil
More information about the PyQt
mailing list