QModelRoleDataSpan Class

The QModelRoleDataSpan class provides a span over QModelRoleData objects. More...

Header: #include <QModelRoleDataSpan>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
Since: Qt 6.0

Detailed Description

A QModelRoleDataSpan is used as an abstraction over an array of QModelRoleData objects.

Like a view, QModelRoleDataSpan provides a small object (pointer and size) that can be passed to functions that need to examine the contents of the array. A QModelRoleDataSpan can be constructed from any array-like sequence (plain arrays, QVector, std::vector, QVarLengthArray, and so on). Moreover, it does not own the sequence, which must therefore be kept alive longer than any QModelRoleDataSpan objects referencing it.

Unlike a view, QModelRoleDataSpan is a span, so it allows for modifications to the underlying elements.

QModelRoleDataSpan's main use case is making it possible for a model to return the data corresponding to different roles in one call.

In order to draw one element from a model, a view (through its delegates) will generally request multiple roles for the same index by calling data() as many times as needed:

 QVariant text = model->data(index, Qt::DisplayRole);
 QVariant decoration = model->data(index, Qt::DecorationRole);
 QVariant checkState = model->data(index, Qt::CheckStateRole);
 // etc.

QModelRoleDataSpan allows a view to request the same data using just one function call.

This is achieved by having the view prepare a suitable array of QModelRoleData objects, each initialized with the role that should be fetched. The array is then wrapped in a QModelRoleDataSpan object, which is then passed to a model's multiData() function.

 std::array<QModelRoleData, 3> roleData = { {
     QModelRoleData(Qt::DisplayRole),
     QModelRoleData(Qt::DecorationRole),
     QModelRoleData(Qt::CheckStateRole)
 } };

 // Usually, this is not necessary: A QModelRoleDataSpan
 // will be built automatically for you when passing an array-like
 // container to multiData().
 QModelRoleDataSpan span(roleData);

 model->multiData(index, span);

 // Use roleData[0].data(), roleData[1].data(), etc.

Views are encouraged to store the array of QModelRoleData objects (and, possibly, the corresponding span) and re-use it in subsequent calls to the model. This allows to reduce the memory allocations related with creating and returning QVariant objects.

Finally, given a QModelRoleDataSpan object, the model's responsibility is to fill in the data corresponding to each role in the span. How this is done depends on the concrete model class. Here's a sketch of a possible implementation that iterates over the span and uses setData() on each element:

 void MyModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
 {
     for (QModelRoleData &roleData : roleDataSpan) {
         int role = roleData.role();

         // ... obtain the data for index and role ...

         roleData.setData(result);
     }
 }

See also Model/View Programming and QAbstractItemModel::multiData().