Create a QModelIndex from a Data Item

2.5k Views Asked by At

I'm looking for a way to create a QModelIndex from a particular piece of data in my model. I can go from a QModelIndex to a data item via:

CustomData *data = static_cast<CustomData *>(modelIndex.internalPointer());

But I'm looking for an inverse function to go from:

QModelIndex *index = createIndex(data); // ??

I've implemented linkages between my data very similar to the simple tree model example (http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html). My view displays the data correctly, but with considerable lag. I'd like to emit dataChanged(QModelIndex, QModelIndex) to see updates to the view instantly, since I think the lag is due to waiting for the view to update.

In the linked example, I'm trying to get from a TreeItem to its corresponding index in the QTreeModel.

2

There are 2 best solutions below

0
On

You can't use traditional indicies because in the Model/View programming they don't stick around, unless you use:

QPersistentModelIndex

http://doc.qt.io/qt-5/qpersistentmodelindex.html#details

Also there are a lot of new paradigms introduced with the Model/View programming. The documentation on it and using it has a learning curve... read through it a few times and try using the examples bundled with Qt Creator that use them.

More about using QPersistentModelIndex

http://doc.qt.io/qt-5/model-view-programming.html#using-model-indexes

Model indexes provide temporary references to pieces of information, and can be used to retrieve or modify data via the model. Since models may reorganize their internal structures from time to time, model indexes may become invalid, and should not be stored. If a long-term reference to a piece of information is required, a persistent model index must be created. This provides a reference to the information that the model keeps up-to-date. Temporary model indexes are provided by the QModelIndex class, and persistent model indexes are provided by the QPersistentModelIndex class.

To obtain a model index that corresponds to an item of data, three properties must be specified to the model: a row number, a column number, and the model index of a parent item...

0
On

The view doesn't update periodically. It updates as needed, and from the point of view of your model, that means anything. If your model doesn't emit dataChanged when an item changes one or more of its data role values, then your model is simply broken.

To fix it, you have two approaches:

  1. Add the row and column to CustomData. You'll have to keep these updated as you add/remove rows/columns.

  2. When needed, iterate the items in the parent of your item to find the child - when you do, you get the row/column from the loop that iterates the items.

I think that you're trying too hard, through. You most likely do not need to implement CustomData at all - but merely use QStandardItem and store the data in the variant. Then, QStandardItemModel handles all the details of iterators and signals for you. To store a custom data type in the QVariant that the QStandardItem uses for storage, simply expose it to the QVariant machinery via Q_DECLARE_METATYPE(YourType).

You'd need to provide a convincing argument that somehow a QStandardItem is insufficient for your needs.