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

Reply via email to