[PyKDE] SIP automatically casting up to a QWidget

Phil Thompson phil at riverbankcomputing.co.uk
Fri Feb 23 00:58:18 GMT 2007


On Thursday 22 February 2007 6:49 pm, Paul Giannaros wrote:
> On Thursday 22 February 2007 17:10, Giovanni Bajo wrote:
> > On 2/22/2007 5:32 PM, Paul Giannaros wrote:
> > >>> I have a class A that i'm wrapping with SIP. The class inherits from
> > >>> a bunch of other classes. One of the classes it inherits from also in
> > >>> turn inherits from QWidget. When I import the created module,
> > >>> whenever I call a method that is meant to return an instance of class
> > >>> A I get a QWidget instead. I can use sip.cast to get the QWidget back
> > >>> to an A instance, but that's not a very friendly solution.
> > >>> Can someone suggest why this is happening, or how to fix it?
> > >>
> > >> SIP needs to know the correct run-time type of your class: otherwise
> > >> when it receives a QWidget* it cannot know what type the class really
> > >> is.
> > >>
> > >> Have a look at how %ConvertToSubClassCode is implemented in
> > >> QtCore/qobject.sip and QtGui/qapplication.sip (assuming you're using
> > >> Qt4). Within your a.sip, you must add your own %ConvertToSubClassCode
> > >> that verifies if a generic QObject* is an instance of your type (class
> > >> A). SIP then knows how to "chain" all the other %ConvertToSubClassCode
> > >> in the object hierarchy, so your code needs only to verify your own
> > >> class.
> > >
> > > But I don't see why it's receiving a QWidget* -- the return type of the
> > > functions i'm calling are explicitly A*.
> >
> > Because elsewhere, in a point of your code that you are probably
> > ignoring, the instance is being returned as QWidget*. SIP executes the
> > %ConvertToSubClassCode *once* and create a Python object of type
> > QWidget; it register this Python an object within a hash table. After
> > that, every time the instance is returned by *any* method, it's looked
> > up in the hash table, and the Python wrapper (already constructed) is
> > found.

That can happen, but only if the object is first returned before the module 
defining the more specific class is imported (ie. before the convertor code 
handling the more specific class is loaded).

> > > Nevertheless, I implemented %ConvertToSubClassCode in class A (and
> > > class B which inherits QWidget) using
> > > sipMapStringToClass/sipStringTypeClassMap, and a QWidget is still being
> > > returned.

The convertor code fragments are invoked in the reverse order that the modules 
were imported (or implicitly imported as a module will import the modules it 
depends on before registering itself with the sip module). In other words, an 
object will be given a class of QWidget if no other more specific modules 
have identified it as a more specific class. If you think your (more 
specific) module does identify it as a more specific class, then 
your %ConvertToSubClassCode is probably buggy.

Phil




More information about the PyQt mailing list