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

Gerard Vermeulen gvermeul at grenoble.cnrs.fr
Wed Oct 22 12:36:00 BST 2003


On Wed, 22 Oct 2003 10:56:33 +0100
Phil Thompson <phil at riverbankcomputing.co.uk> wrote:

> 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.
> 
Oops, not yet ready to try SIP-v4 on PyQwt, yet. And I also have Qwt
duties tonight :-).  But I'll try to give it a try :-)

To illustrate the problem (Phil, I know you understand it), clearly:

    def eventFilter(self, object, event):
        if event.type() == QEvent.Resize:
            size = event.size()
            print (
                'Sometimes object and self.axis(QwtPlot.yLeft) "hold" the\n'
                'the same pointer, but they are different Python objects'
                )
            print object, self.axis(QwtPlot.yLeft)
            print 'isA test:', object.isA("QwtScale")
            print 'is test:', object is self.axis(QwtPlot.yLeft)
            if object is self.axis(QwtPlot.yLeft):
                print 'Wow' # never see wow
                ...

gives:

[packer at venus examples]$ ./EventFilterDemo.py
Sometimes object and self.axis(QwtPlot.yLeft) "hold" the
the same pointer, but they are different Python objects
<qt.QObject instance at 0x828f61c> <qwt.QwtScale instance at 0x828c5f4>
isA test: 1
is test: 0
....

Gerard




More information about the PyQt mailing list