[PyQt] Problem with implementation of dummy (no-op) proxy model

Hans Meine meine at informatik.uni-hamburg.de
Thu Oct 28 10:18:48 BST 2010


Hi Hans-Peter,

thanks for your reply.

Am 27.10.2010 um 22:17 schrieb Hans-Peter Jansen:
> Not here. After fixing the obvious bug in headerData to actually call 
> headerData, I get (with needPersistentModelIndex = False):

Yes, headerData() was broken; actually, AFAIK it is not even necessary at all, same for flags() (I added both in my desperate search for a fix, but would prefer to remove them again).

> 1) rowCount: 10
> 
> 2) got root index <PyQt4.QtCore.QModelIndex object at 0x8175d4c> 
> (isValid: True)
> 
> 3) got base index <PyQt4.QtCore.QModelIndex object at 0x8175d14>

Hmm, that looks strange; I had a special __repr__ for debug output, did you remove that code?  Without it, it does not crash for me either, but that's because no method on the QModelIndex'es is ever exercised.  (For instance, parent() seems to be critical.)

> and
> 
> 1) rowCount: 10
> 
> 2) got root index <PyQt4.QtCore.QModelIndex object at 0x8175d14> 
> (isValid: True)
> 
> Traceback (most recent call last):
>  File "dummy_proxy.py", line 99, in <module>
>    j = model._baseIndex(i)
>  File "dummy_proxy.py", line 21, in _baseIndex
>    baseIndex.row(), baseIndex.column(), baseIndex.parent())
> RuntimeError: underlying C/C++ object has been deleted
> 
> for the other variant.

OK, that looks interesting, so QPersistentModelIndex is really needed?

As I understood persistent indices, they're only needed if the model layout changes, e.g. rows inserted or removed.

> I must confess, that I don't grok your _baseIndex, index and parent 
> methods for the persistant index case, especially the 
> 
> 		baseIndex = self._baseModel.index(
>                        baseIndex.row(), baseIndex.column(), 
>      			baseIndex.parent())

Yes, I expected there to be a simpler way of turning a QPersistentModelIndex into a QModelIndex, but I could not find any.  So I simply take the characteristic properties of the index (row, col, & parent) and create a fresh one.

(I am probably explaining something obvious, but the basic idea was just that internalPointer() would not contain a QModelIndex anymore, but a corresponding QPersistentModelIndex.)

> but I'm really tired already..
> 
> The real question is, why don't you base your proxy model on 	
> QProxyModel, it's made exactly for your aspired purposes, AFAICS.

Oh, I only knew QSortFilterProxyModel, which is a fine class, but not suitable for me since I want to *add* (not filter) rows.  QProxyModel is indeed only sparsely documented, i.e. it does not appear in the model/view docs.  Oh, maybe because it's deprecated..

And QAbstractProxyModel is also intended only for sorting/filtering (and maybe data processing), but not for adding rows AFAICS.  I would have problems with implementing mapToSource on indices that do not exist in the source.  Then again, a filtering model would have the same problem with mapFromSource, so I will have a look whether it helps.

> If you really want to bake your own, I would start with a C++->Python 
> conversion of that module, and enhance as required. 

That could be a way, yes.

I just wondered what my problem was, since I have some experience with Qt's model/view architecture and custom models, and a custom model that just proxies another model did not appear to be more difficult to implement than a model that references data in another class, to the contrary.  Sigh. I probably made a stupid error which I am not able to see anymore.

(Last time I had crashes like this, I derived from QAbstractListModel, but only called QAbstractItemModel.__init__...)

Thanks again and have a nice day,
  Hans


More information about the PyQt mailing list