Доступ к элементу QAbstractListModel в Qml без использования ListView

Я подкласс QAbstractListModel для того, чтобы иметь модель на стороне qml. Я могу легко использовать эту модель в ListViews и других подобных компонентах, которые имеют дело с моделями, однако я не могу получить к ней доступ напрямую. Вот что я пытаюсь без успеха:

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

Это возможно? Я использую неправильный синтаксис?

3 ответа

Вы можете получить доступ к общей модели (на основе QAbstractListModel) легко, когда вы используете модель DelegateModel в качестве посредника.

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) Вы смешиваете роли и свойства.

Ваша модель реализует роли, которые используются для подачи делегата в представлении. В вашем коде вы пытаетесь получить доступ к свойству.

(2) Модель не является массивом, где вы можете получить доступ к строкам с помощью [] оператор.

Но можно написать функцию получения для архивирования именно этого:

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:
    // ...

Чем вам нужен тип данных, представляющий строку, например ConversationModel, Теперь вы можете получить доступ к строке, используя

myModel.get(0).name

Как указано в (1), теперь вам нужно дать ConversationModel свойство называется name

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

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

Чтобы заставить (правильное) решение Simon Warta работать, вы должны зарегистрировать ConversationModel как тип QML. Например, в своей главной вы должны указать

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

Затем в вашем файле qml вы должны импортировать этот тип с

import ConversationModel 1.0

После этого все работает как положено, и вы можете использовать

myModel.get(0).name

в вашем qml-коде, учитывая, что myModel имеет тип ConversationListModel и был зарегистрирован с использованием QDeclarativeContext:: setContextProperty.

Другие вопросы по тегам