[PyKDE] How to test if two PyQt instances wrap the same C++ object?

Phil Thompson phil at riverbankcomputing.co.uk
Wed Oct 22 11:58:01 BST 2003


On Wednesday 22 October 2003 9:19 am, Gerard Vermeulen wrote:
> Hi,
>
> I have difficulty to translate this C++ idiom in Python:
>
> bool Plot::eventFilter(QObject *object, QEvent *e)
> {
>     if ( e->type() == QEvent::Resize )
>     {
>         const QSize &size = ((QResizeEvent *)e)->size();
>         if ( object == (QObject *)axis(yLeft) )  // HOW TO THIS IN PYTHON?
>         {
> 	// ...
>         }
>     }
>
>     return QwtPlot::eventFilter(object, e);
> }
>
> Of course I could write for PyQwt a function:
>
> qwt.compareCPlusPlusPointers(SuperObject, DerivedObject)
>
> but if it is really needed, it belongs in PyQt.

Have you tried the obvious and it doesn't work?

PyQt keeps a map of all C++ pointers and Python instances that it knows about. 
When it wraps a C++ pointer it first checks if it already knows about the 
pointer (while doing a bit of type checking). If it does then it just returns 
a new reference to the existing Python instance. In other words...

    if object is axis(yLeft):

...should work. However...

The "bit of type checking" deals with the common case where PyQt first wraps a 
C++ pointer with a more specific type (eg. QLabel) and then is asked to wrap 
it as a less specific type (eg. QWidget). It *doesn't* handle the less common 
case (eg. the code above) when it sees the less specific type first (QObject) 
and the more specific type second (whatever axis() returns).

The code to change is sipOMFindObject() in siplib/objmap.c. In SIP v4 change 
the single call to PyType_IsSubtype() to...

        if (PyType_IsSubtype(w -> ob_type,&type -> super.type) ||
            PyType_IsSubtype(&type -> super.type,w -> ob_type))
                return w;

(I think the SIP v3 change is slightly more complicated.)

Let me know if that works.

Phil




More information about the PyQt mailing list