Hi Bogdan,
Perhaps I misunderstood, but isn't `QPersistentModelIndex` Qt's current
solution to your motivational example of needing to keep a model index
beyond the current event loop tick? How does it currently fall short?
My understanding is that `QModelIndex` is intended as a lightweight and
cheap to copy reference into a model as it exists at the moment it was
created, very much akin to a STL iterator. I think that having it hold
arbitrary data, or participate in the ownership of the model data, goes
against that.
Best,
Igor
On 01/07/2026 16:02, Bogdan Vatra via Development wrote:
Hello there,
I'd like to propose a new accessor on QModelIndex for Qt 7 and get feedback
from the list:
QVariant QModelIndex::internalData() const;
or
std::any QModelIndex::internalData() const; // as std::any is 1/2 of
sizeof(QVariant).
Why?
QModelIndex currently exposes two ways for a model to attach opaque context to
an index:
quintptr QModelIndex::internalId() const;
void *QModelIndex::internalPointer() const;
Both work well for *static* model content, where the model's backing data
lives for as long as the model itself.
They fall short for *dynamic* models, where individual items can be created,
moved, or destroyed independently of any QModelIndex that currently references
them.
Let me give you an example which will randomly crash a QSortFilterProxyModel:
// main loop has a QAbstractItemModel::dataChanged (or any other QAIM signal
which will reset the idx internalPointer) event posted, e.g by another thread
// get an idx
myView->setCurrentIndex(idx);
myView->scrollTo(idx); // At this point there is no way to know if idx is
still valid. It depends on what `myView->setCurrentIndex(idx);` is doing and
there is no way to know if internalPointer is still valid or not. If inside of
that method QCoreApplication::processEvents is called, myView->scrollTo(idx)
gets an invalid idx...
How my proposal fixes this problem?
In a QVariant/std::any we can store a smart pointer and this way the data is
valid all the time. It can still hold a plain quintptr for models that don't
need this, so internalId()/internalPointer() could become thin wrappers around
the same underlying storage instead of needing a member variable of their own.
Cheers,
BogDan.
P.S. It can not go in Qt6 as it will break the ABI ...
--
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development