[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