关于qt:在Qml中访问QAbstractListModel项而不使用ListView

Accessing QAbstractListModel item in Qml without using a ListView

我已经将QAbstractListModel子类化,以便在qml方面具有模型。 我可以在ListViews和其他处理模型的类似组件中轻松使用此模型,但是,我无法直接访问它。 这是我没有成功的尝试:

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

这可能吗? 我使用的语法错误吗?


当您使用DelegateModel模型作为中介时,可以轻松访问通用模型(基于QAbstractListModel)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)模型不是数组,您可以在其中通过[]运算符访问行。

但是您可以编写一个getter函数来实现以下目的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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。现在您可以使用

1
myModel.get(0).name

如(1)中所述,您现在需要给ConversationModel一个名为name的属性。

1
2
3
4
5
public:
    explicit ConversationModel(QObject *parent = 0);

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

为了使Simon Warta(正确的)解决方案有效,您必须将ConversationModel注册为QML类型。例如,在您的主体中,您必须声明

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

然后在您的qml文件中,您必须使用

1
import ConversationModel 1.0

之后,一切都会按预期进行,您可以使用

1
myModel.get(0).name

在qml代码中,假设myModel是ConversationListModel类型,并且已使用QDeclarativeContext :: setContextProperty注册。