QML Model data by index

早过忘川 提交于 2021-02-07 20:54:10

问题


I have QAbstractListModel based model...

class RecordModel : public QAbstractListModel { ... };

QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("recordModel", &model);

// QML
recordModel.get(0).name // now work

How to get a model data by index and role name?

... Solution:

// C++
class RecordModel : public QAbstractListModel
{
   Q_OBJECT
   Q_ENUMS(Roles)

   public:
      // ...
      Q_INVOKABLE QVariant data(int i, int role) const
      {
          return data(index(i, 0), role);
      }
};

// QML
recordModel.data(0, RecordModel.NameRole);

回答1:


You should only use a Q_INVOKABLE method for specific functionalities that you want to be able to call from QML. Unless you somehow want to access model data from without access to the delegate of your model, you should always use the more proper model<->delegate way of getting the data.

Since you're inheriting from QAbstractListModel, it'll work like QAbstractItemModel.

Declare roles as shown:

enum Roles {
    RoleA = Qt::UserRole + 1,
    RoleB = Qt::UserRole + 2
};

Override this method to allow QML access using roles:

QHash<int, QByteArray> RecordModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[RoleA] = _Ut("roleA");
    roles[RoleB] = _Ut("roleB");
    return roles;
}

Override this method to return data when QML tries to access:

QVariant RecordModel::data(const QModelIndex &modelIndex, int role) const
{
    QVariant rv;
    int index = modelIndex.row();

    switch( role ) {
    case RoleA:
        rv = "A";
        break;
    case RoleB:
        rv = "B";
        break;
    default:
        DASSERT(FALSE);     // Unexpected role.
        break;
    }

    return rv;
}

Then in QML you'll simply use "roleA" and "roleB" in the delegates of the QML Element that uses this model to access the data.

References:

http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html

http://qt-project.org/doc/qt-5.0/qtcore/qabstractlistmodel.html




回答2:


You can use Q_INVOKABLE method:

Q_INVOKABLE QVariant getRecord(int iIndex)
{
    return QVariant::fromValue<CRecord*>((CRecord*)this->at(iIndex));
}

And then in QML:

recordModel.getRecord(0)

You will just need to declare a metatype:

Q_DECLARE_METATYPE( RecordModel* )

And somewhere in main.cpp:

qmlRegisterType<RecordModel>("PrivateComponents", 1, 0, "RecordModel");
qmlRegisterType<CRecord>("PrivateComponents", 1, 0, "CRecord");


来源:https://stackoverflow.com/questions/20398646/qml-model-data-by-index

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!