if you want to use the classic approach for roles in list models you don't have to do anything special in the c++ side, you have your model like always and it should implement the data method:
QVariant QAbstractItemModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const
to access the different roles from QML the model
attached property can be used in your ListView delegate:
model.display // model.data(index, Qt::DisplayRole) in c++
model.decoration // Qt::DecorationRole
model.edit // Qt::EditRole
model.toolTip // Qt::ToolTipRole
// ... same for the other roles
I don't think that is anywhere documented in the Qt doc (yet), but to find out what properties you can access form QML just start the app in debug mode and put a breakpoint in the delegate or print all properties to the console. Btw the model
property inside the delegate is of type QQmlDMAbstractItemModelData, so there is some "Qt magic" happening in the background, looks like some wrapper around the list model data, still I could not find anything official in the Qt documentation about that (I figured that out by myself with the QML debugger and stuff).
If you need to access the model data from outside of the delegate I don't think there is any build in functionality for that, so you have to do that yourself.
I did an example for a custom QAbstractListModel class which exposes a count
property and get
-function similar to the default QML ListModel:
mylistmodel.h
class MyListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit MyListModel(QObject *parent = 0);
int rowCount(const QModelIndex & = QModelIndex()) const override { return m_data.count(); }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE int get(int index) const { return m_data.at(index); }
signals:
void countChanged(int c);
private:
QList<int> m_data;
};
mylistmodel.cpp
MyListModel::MyListModel(QObject *parent) :
QAbstractListModel(parent)
{
m_data << 1 << 2 << 3 << 4 << 5; // test data
emit countChanged(rowCount());
}
QVariant MyListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
return QVariant();
int val = m_data.at(index.row());
switch (role) {
case Qt::DisplayRole:
return QString("data = %1").arg(val);
break;
case Qt::DecorationRole:
return QColor(val & 0x1 ? Qt::red : Qt::green);
break;
case Qt::EditRole:
return QString::number(val);
break;
default:
return QVariant();
}
}
Since it is pretty easy to expose properties and functions to QML I guess this a good way to do it for know.
For completeness here an example ListView using my custom model:
ListView {
anchors.fill: parent
model: MyListModel { id: myModel }
delegate: Text {
text: model.display
}
Component.onCompleted: {
console.log(myModel.count) // 5
console.log(myModel.get(0)) // 1
}
}