[Qt5-feedback] Add internalVariant to QModelIndex

Charley Bay charleyb123 at gmail.com
Tue Jul 12 19:13:21 CEST 2011


>
> Charley Bay wrote:
>
> > I completely support Matthias' proposal for an internal "variant" type
> > thing
> > for QModelIndex.
>
> Stephen Kelly responded:

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

Thanks for the correction.  And, I agree Matthias' issue likely would not be
solved by an internalVariant (it seems his work-around is to respect the
irritating Q_ASSERT_X() that may not be perfect in all cases, depending on
how the void* was created referencing the same object instance).


> > 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() )
> <snip>,
>


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

Yes -- I don't want the Node class at all.

For example, consider a "MyBook" object that contains "MyChapter" objects,
each of which contain "MyParagraph" objects.  I want to "expose" that
"model" to the Qt MVC by creating QModelIndex instances that reference those
objects, and they do not share a common base class.

We have *many* such models, and indeed, every application has its own
logical "model implementations" that are not GUI and not implemented with
consideration of possible future coupling to the Qt MVC infrastructure.
These "models-of-heterogeneous-types" are terribly common.

IMHO, this issue is increasingly dramatic with QML, where interface
components are increasingly "independent actors", but which should logically
be "identifiable" through a QModelIndex-type handle to reference the
"relevant node state" from some application, especially when that "relevant
node state" may actually be virtual (e.g., an aspect of an object or
collection of objects, not an object itself).

> 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?
>

>From the Qt APIs I see:

  QModelIndex QAbstractItemModel::createIndex(int row, int column, void*
ptr) const;
  QModelIndex QAbstractItemModel::createIndex(int row, int column, quint32
id) const;

Can I have *both* a "void*" *and* a "quint32"?  (I thought they were
union'd).

If I can have *both*, then yes, that would help (a lot).  Do we want an
overloaded createIndex() that takes both, or some update to the API
documentation?

> 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.
>

For me, Node is *also* temporary.  In the example above, we keep MyBook,
MyChapter, and MyParagraph instances, because those are the "real" model
(and they do not share a common base class).

Our work-around creates a MyBookNode class for the sole purpose of exposing
our "real" model to the Qt QML infrastructure.  The MyBookNode instance can
reference any model object, and we must have a maintained/synchronized tree
of MyBookNode instances that reference the *real* model.  (I'd be much
happier if we did not have this tree at all.)

Restating:

(1)- MyBookNode only exists because QModelIndex has a typeless void*, and I
don't know what type it points to.  (I thought you could not have
QModelIndex::internalId() in addition to QModelIndex::internalPointer()?)

(2)- The maintined/synchronized tree of MyBookNode instances only exists
because QModelIndex cannot perform value semantics on the MyBookNode
(temporary and volatile) handle.

Great happiness and joy throughout the land comes from a QModelIndex design
change that removes (2), or (1) (and removing (1) similarly means removing
(2)).


> > 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. <snip>,
>

<snip>,
> 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.
>

That case *does* come up, but in this context we are specifically trying to
drop (2) above, where we "cache/maintain/synchronize" the tree-of-MyBookNode
instances.  The MyBookNode life-cycle, ideally, would only exist for the
QModelIndex lifecycle (so we would not have that cache tree at all).


> > 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.
>

I only need value semantics so MyBookNode "goes away" when the QModelIndex
goes away.  The "ideal" solution would be for me to not have MyBookNode at
all, and for QModelIndex to directly reference MyBook, MyChapter, and
MyParagraph objects.  But currently, given a QModelIndex, I don't know which
of those objects is inside that void*.


> > (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 defer to the Trolls how they want to deal with that.  If value semantics
within QModelIndex were a goal, I'd be fine with a QSharedPointer-type
thing, with the void* being replaced with a typed QPayload* that the user
overrides and is always deleted by the QModelIndex, or any other mechanism
to permit a small payload for user state that is "wholly contained" within
the QModelIndex.  (I only need a void* and an enum).

However, I would guess the easier approach would be to simply add a
(user-definable) enum *in addition* to the existing void*, so I can merely
cast the void* to a MyParagraph or MyChapter, as needed.

Can I have *both* the void* and the internal id in a QModelIndex?  That
*would* make me happy.  (How do I create that?)

--charley
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt.nokia.com/pipermail/qt5-feedback/attachments/20110712/1a09b650/attachment.html 


More information about the Qt5-feedback mailing list