Доступ к элементу 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.