[Qt5-feedback] Add internalVariant to QModelIndex

Stephen Kelly steveire at gmail.com
Tue Jul 12 17:51:20 CEST 2011


Charley Bay wrote:

> I completely support Matthias' proposal for an internal "variant" type
> thing
> for QModelIndex.

I think Nils suggested it. I'm not certain Matthias' issue would be solved 
by an internalVariant.

> My use case is different, but my solution was the same
> as
> what Matthias implemented:  Generate a "permanant tree" of utility
> instances (handles) that reference the "real" stuff in the model, because
> QModelIndex
> cannot resolve the type of object it references.  (This intermediate tree
> is difficult to maintain/synchronize with model changes, and should be
> completely unnecessary.)

I don't get the need for a permanent tree of utility handles.

See how it's done in the EntityTreeModel:

https://projects.kde.org/projects/kde/kdepimlibs/repository/revisions/master/entry/akonadi/entitytreemodel_p.h#L42

There is a Node type which can reference either a Collection or an Item. A 
pointer to a node is used for the internalPointer (see ETM::index() )

  return createIndex( row, column, reinterpret_cast<void*>( node ) );

And when nodes are created they are also stored internally in the model:

  QHash<Collection::Id, Collection> m_collections;
  QHash<Entity::Id, Item> m_items;
  QHash<Collection::Id, QList<Node*> > m_childEntities;

In ETM::data() I get an internalPointer, cast it to a Node*, check the type, 
check the id, and return what was requested.

  const Node *node = reinterpret_cast<Node *>( index.internalPointer() );
  if ( Node::Collection == node->type ) {

    const Collection collection = d->m_collections.value( node->id );

    if ( !collection.isValid() )
      return QVariant();

    switch ( role ) {
      case MimeTypeRole:
        return collection.mimeType();

// ... etc

Is this what you mean to be the problem? Is my Node like the 'utility 
instance' you refer to?

> 
> I understand the issues regarding performance and the current trivial
> constructor/copy-constructor for QModelIndex, so I can "settle" for an
> *additional* int-or-enum value (in addition to the current void* inside
> the QModelIndex).

There is 

int QModelIndex::internalId() 

already. Does that help?

> 
> Our use case, very painful:  Applications commonly use "native" models of
> heterogeneous types, and we need to create QModelIndex references to those
> model "nodes".  With the current "void*", we do not know the *type* to
> which
> it points.  So, we create an "adapter utility" instance that *does* know
> the
> type.  Unfortunately, these "adapter utility" instances come-and-go like
> the QModelIndex comes-and-goes, 

I don't think the Node* has the same lifecycle as a QModelIndex. A 
QModelIndex is temporary.

> and the current Qt MVC design provides no
> possible mechanism to delete these "adapter utility" instances.

I think I understand what you're saying here. 

To be more concrete, lets talk about a filesystem model. 

1) When the model::rowCount, or hasChildren, or fetchMore or canFetchMore or 
whatever is called for a particular folder, you can look at what is in the 
folder, create some Node*s of with an enum telling you if it is type 
directory or file, and store them in a sequential container like a QList.

2) When model::index is called, you do something like 
createIndex(indexInQList, 0, node);

3) When data is called you do something similar to what I did with the ETM.

At this point maybe nothing else wants the nodes you created, so you want to 
delete the Node*s that are no longer needed. Is that right? Is that the 
issue you are describing? You want to be told when you can 'forget' about 
stuff?

If that is the problem then I think there are better ways to solve it than a 
internalVariant.

> We need
> value semantics inside the QModelIndex itself, or the ability to inspect
> the "void*" from the QModelIndex to know *what type* it references.

I don't see how knowing the type can have any effect on knowing when you can 
delete stuff.

> 
> (Because there is no possible mechanism for value semantics for these
> "adapter utility" instances, we have a permanently maintained "utility
> instance tree" that mirrors the *real* model, just as did Matthias.)
> 
> This is my *only* serious problem with the Qt model/view infrastructure,
> and it is a (very) big problem.
> 
> Previous discussion at: <
> http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000047.html>
> 

You suggest that QModelIndex [should] wholly-contain a MyHandleToMyObject 
type (through pointer that it deletes)

That doesn't seem right to me for several reasons. First, it means that 
you'd have to new something every time index() is called and use it with 
createIndex() so that the QModelIndex takes ownership of it (assuming you 
could tell the QModelIndex the concrete type - it can't delete void*). 
QModelIndex would also have to become something like a QSharedPointer.

I didn't read the 2006 thread. It's getting late in the work day here.


Thanks,

Steve.




More information about the Qt5-feedback mailing list