[PyKDE] Is There a HOWTO for using PyQt in an existing Qt application?

Jim Bublitz jbublitz at nwinternet.com
Sat Jul 10 18:51:00 BST 2004


On Saturday 10 July 2004 06:36, Clay Hopperdietzel wrote:

> The QApplication and QMainWindow for the applications are in C++, and,
> because of their relationships with the Motif underpinnings, really need
> to stay in that form.  I would, however, like to find a way to create
> PyQT elements atop this framework.

> I would expect that probably an expert on the inner workings of SIP
> could lay out an answer quickly, but alas, I haven't had time to delve
> into it to the required level.

In sip 4.0 Phil added a couple of new functions to sip itself that are 
callable from Python:

    from sip import wrapinstance, unwrapinstance

These are covered in the new sip docs, but without any examples. You'd 
basically use them like this  (for example, passing QMainWindow as a parent 
for a widget to be constructed in Python):

In C++:

// Make the pointer to QMainWindow a PyObject (or cast to QMainWindow
// if you've subclassed it)

QMainWindow *mainWindowPtr = QMainWindow ( ... ) 

PyObject *mw = PyLong_FromVoidPtr ((void *) mainWindowPtr);
PyObject *args = Py_BuildValue ("N", mw);

// Assume 'pyfunc' is a callable object for 'pyFunction' in your script

PyObject *result = PyObject_CallObject (pyfunc, args);

----------------------

In Python:

from qt import QMainWindow, QLabel
from sip import wrapinstance, unwrapinstance

def pyFunction (parent):
# parent is a C++ ptr to QMainWindow as a number (long)
# make it a QMainWindow instance in Python:

    pyMW = wrapinstance (parent, QMainWindow)

# create a QLabel with the Main Window as parent

    lbl = QLabel ("A Label", pyMW)
    lbl.setGeometry ( ... )

# get the C++ ptr to the underlying QLabel instance and
# pass it back to C++

    cppLbl = unwrapinstance (lbl)
    return cppLbl

-------------------------------------------

Back in the original C++ file:

QLabel *label = (QLabel *)PyLong_AsVoidPtr (result);

(obviously this line follows the PyObject_CallObject line in sequence in the 
code)

The objects you pass from C++ to Python have to be objects supported by some 
bindings like PyQt or PyKDE (you're not limited to just QMainWindow), or you 
can write thin wrappers for your own APIs and pass their objects back and 
forth. You can use sip to do this of course - sip 4.0 has very good docs, and 
you can use PyQt and PyKDE as sample code.

You don't need to do a full set of bindings like PyQt or PyKDE - you can write 
a simple interface layer (wrapper) in C++, compile it as a .so, and then use 
sip to build bindings (importable Python modules) for that interface layer. 
You could also do a plugin interface.

In the example above, you C++ program doesn't need to know anything about sip 
or PyQt  and doesn't link to sip.so or qt.so - all conversions are done on 
the Python side.
 
> So, has anybody done this, documented it, or have some small example out
> there?  For extra points, my ultimate goal would be to get at least
> parts of the eric3 IDE running in the embedded interpreter (help the
> user build his scripts).

I really have no idea about eric3, but it should be possible - I'd start by 
looking at eric3's __main__ and see what you'd need to do to load it as a 
module and execute it.

You'll likely be more successful with sip4 than sip3.

Jim




More information about the PyQt mailing list