1
votes

I have subclassed QAbstractListModel in order to have a model on the qml side. I can easily use this model in ListViews and other similar components that deal with models, however, I can't access it directly. This is what I am trying without success:

myModel[0].name // TypeError: Cannot read property 'name' of undefined

Is this possible? Am I using the wrong syntax?

3
Show your code please. At least myModel initialization in QMLfolibis

3 Answers

1
votes

You can access generic model (based on QAbstractListModel) easily when you use DelegateModel model as a mediator.

import QtQuick 2.2
import QtQml.Models 2.2

DelegateModel {
  id: delegateModel
}
MyModel {
  id: myModel
  onDataLoaded: {
    delegateModel.model = myModel;
    for (var row = 0; row < myModel.rowCount(); row++) {
      var item = delegateModel.items.get(row).model;
      console.log("  name " + row + ":" + item.name);
    }
  }
}
1
votes

(1) You're mixing up roles and properties.

Your model implements roles which are used to feed a delegate in a view. In your code, you try to access a property.

(2) A model is not an array, where you can access rows by the [] operator.

But you can write a getter function to achieve exactly that:

class ConversationListModel : public QAbstractListModel
{
    Q_OBJECT

public:
    enum ConversationRoles {
        IdRole = Qt::UserRole, // 256
        NameRole,
    };
    explicit ConversationListModel(QObject *parent = 0);
    QHash<int, QByteArray> roleNames() const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;

    Q_INVOKABLE ConversationModel* get(quint32 conversationId) const;

signals:
    // ...

Than you need a data type that represents a row, e.g. ConversationModel. Now you can access a row using

myModel.get(0).name

As stated in (1), you now need to give ConversationModel a property called name

public:
    explicit ConversationModel(QObject *parent = 0);

    Q_PROPERTY(QString name READ name NOTIFY nameChanged)
    QString name() const;
0
votes

To make the (correct) solution of Simon Warta work, you have to register ConversationModel as QML type. For example in your main you have to state

qmlRegisterType<ConversationModel>("ConversationModel", 1, 0, "ConversationModel");

Then in your qml file you have to import this type with

import ConversationModel 1.0

Afterwards everything works as expected and you can use

myModel.get(0).name

in your qml code, given that myModel is of type ConversationListModel and was registered using QDeclarativeContext::setContextProperty.