[PyKDE] QListView(Item) subclass insertItem strange behaviour, bug?

Phil Thompson phil at river-bank.demon.co.uk
Sun Jan 5 16:50:01 GMT 2003


On Saturday 04 January 2003 6:00 pm, marvelan L wrote:
> Hi list
>
> I have subclassed QListView and QListViewItem in order to be able
> to use my own list view items with additional methods.
>
> I need to call these methods when a list view item is inserted as a
> child to another item. But it does not seem to be possible, read on :-)
>
>
> My problem is that when insertItem of a QListViewItem or QListView is
> called, the object passed to it is a QListViewItem and not my subclass
> that I'm using.
>
> I made a small test program to demonstrate. When I run the code below
> it prints the following:
>
> List class: 'qt.QListViewItem'
> Item class: 'qt.QListViewItem'
>
> It should print something like:
>
> List class: 'MyList'
> Item class: 'MyItem'
>
> The problem is that I need to access my own added methods in MyList when
> insertItem is called. But it seems that it is called with a object of the
> base class and not my specialisation class MyList.
>
> As you can see in the code below I'm not using QListViewItem but instead my
> own MyItem, but still insertItem is called with QListViewItem and not
> MyItem...
>
> Seems like a bug in PyQt (or Qt?) to me, or am I missing something?

It's a subtle feature.

Normally when you create an instance of a Qt sub-class the C++ ctor is called 
and returns a pointer to the new C++ instance. Then that pointer is wrapped 
in the required Python class. PyQt keeps track of all the C++ instances it 
sees and the corresponding Python instance so that if it sees the C++ 
instance again - eg. when it is passed as a parameter to a re-implemented 
virtual - Python sees an object with the more specific class (MyItem) rather 
than the class (QListViewItem) the parameter is defined to have. This is the 
behaviour you are expecting to see.

If PyQt hasn't seen the C++ instance before then it wraps it on the fly using 
the defined class (QListViewItem). This is the behaviour your are actually 
seeing.

The reason is that the QListViewItem ctor is calling its parent's 
insertItem(). This means that insertItem() is being called before the MyItem 
ctor has had a chance to wrap the C++ instance with the right class. In other 
words, the first time that PyQt sees the C++ pointer is in insertItem() and 
the only class information available to it is QListViewItem.

This only affects insertItem(). It will not affect any other virtuals you 
re-implement (unless they are also called by the QListViewItem ctor).

I don't think there is anything I can do about this.

Phil




More information about the PyQt mailing list