[review] [PyKDE] Extraction of Qt objects from a PyObject

Phil Thompson phil at riverbankcomputing.co.uk
Sun Feb 15 00:54:01 GMT 2004


On Saturday 14 February 2004 20:17, Albert Strasheim wrote:
> Hello,
>
> Using sipForceConvertTo_*(), I was able to convert a boost::python::object
> returned via the Boost.Python wrapper around the base class (from which I
> derive a Python class) into a Qt object.
>
> The code to do this looks like this:
>
> // sip function definitions
> extern QEvent* sipForceConvertTo_QEvent(PyObject*, int*);
> extern QKeyEvent* sipForceConvertTo_QKeyEvent(PyObject*, int*);

Don't declare these, do...

#include <sipqtQEvent.h>
#include <sipqtQKeyEvent.h>

...to stop it breaking with SIP v4.

> QEvent* inject()
> {
>   object o = call_method<object>(self, "inject");
>   int iserr = 0;
>   QEvent* e = sipForceConvertTo_QEvent(o.ptr(), &iserr);
>   if ( !iserr )
>   {
>     switch ( e->type() )
>     {
>       case QEvent::KeyPress:
>       case QEvent::KeyRelease:
>       {
>         QKeyEvent* k = sipForceConvertTo_QKeyEvent(o.ptr(), &iserr);
>         if ( !iserr )
>         {
>           return new QKeyEvent(*k);
>         }
>         break;
>       }
>       // more events
>       default:
>       {
>         // unsupported event type returned from Python
>       }
>     }
>   }
>   return 0;
> }
>
> Now I would also like to pass a Qt object to a Python function implemented
> in a class which derives from a C++ class.
>
> To do this, one creates a wrapper class for the base class from which you
> want to derive in Python. The wrapper class dispatches each pure virtual
> function to Python.
>
> The Boost.Python module declaration looks as follows:
>
> BOOST_PYTHON_MODULE(boostqt)
> {
>   class_<MyUnitTest_t::EventHandlerBase_t, EventHandlerBaseWrap,
>     boost::noncopyable>("EventHandlerBase");
>
>   to_python_converter<QEvent, QEvent_to_sipqtQEvent>();
> }
>
> EventHandlerBase_t is the base class from which we wish to derive in
> Python and EventHandlerBaseWrap is the wrapper class.
>
> The to_python_converter<...>() statement takes as first a C++ type and as
> second argument a class implementing a static method called convert()
> which takes a const reference to the aforementioned C++ type and converts
> it to a PyObject*. It is here that we have to translate the Qt object into
> a PyObject containing an instance of the SIP class wrapping the Qt class
> in question.
>
> struct QEvent_to_sipqtQEvent
> {
>   static PyObject* convert(const QEvent& e)
>   {
>     // return something...
>   }
> };
>
> So my question is: what is the right way to convert a Qt type to a
> PyObject*? Since I'm only interested in QEvent's derived types here, I can
> use QEvent::type() with a switch to figure out which derived type I want
> to convert. But what SIP function do I call?

	return sipMapCppToSelfSubClass(&e, sipClass_QEvent);

> Let's look at QKeyEvent as an example. In sipqtQKeyEvent.h (which is
> a generated file), there is a constructor for sipQKeyEvent that takes a
> QKeyEvent as its only argument. Can I convert this sipQKeyEvent instance
> to a PyObject*?
>
> There is also a sipNew_QKeyEvent() function which returns a PyObject*,
> taking two PyObject* arguments. What should I pass to this function? And
> how do I copy the data from my existing QKeyEvent instance into this new
> object (I'm hoping I don't have to write code to do this copying on a
> per-event basis).
>
> By the way, should packages like Red Hat/Fedora's PyQt-devel include
> headers like sipqtQKeyEvent.h? Is there a way to generate these headers
> files given the .sip files (which the -devel package does include)?

In your .sip files (somewhere) you should have a...

%Import qtmod.sip

...which will mean that things like sipqtQKeyEvent.h are generated when you 
run sip.

Phil




More information about the PyQt mailing list