大多数应用程序需要格式化显示数据。Qt Quick具有Models、Views、Delegate的概念,用于显示数据。它们将数据的可视化进行模块化,以便开发者和设计师可以控制数据的不同方面。开发者可以对数据做很少修改的情况下,将列表视图替换为网格视图。同样,通过将数据的一个实例封装在委托Delegate中,开发者可以决定如何呈现或处理数据。

alt text

  • 模型 (Model):包含数据及其结构。QML 提供了多种类型用于创建模型。

  • 视图 (View):用于显示数据的容器。视图可以以列表或网格的形式显示数据。

  • 委托 (Delegate):决定数据在视图中应该如何显示。委托将模型中的每个数据单元封装起来,并通过委托可以访问数据。委托还可以将数据写回可编辑的模型中(例如,在 TextField 的 onAccepted 处理器中)。

要可视化数据,可以将视图的 model 属性绑定到一个模型,将 delegate 属性绑定到一个组件或其他兼容类型。

1 QStringList

QStringList 是由 String 类型的 QList

using QStringList = QList<QString>;

这部分参考的是 Models and Views: String ListModel Example 示例程序。

我修改后的示例程序是 /assets/Qt6/qml_20_models/stringlistmodel/

注意:

  1. 官方示例这里使用的是 setInitialProperties ,该方法仅仅对跟元素的属性有用。我的示例程序修改为 engine.rootContext()->setContextProperty 可以设置所有变量。

  2. QVariant::fromValue(dataList) 形式传入 qml,给模型 model 变量赋值,该模型每一项的值的读取使用的是modelData。(仅仅对于QVariant列表)

alt text

分析存储结构:

alt text

2 QObjectList-based Model

示例程序:/assets/Qt6/qml_20_models/objectlistmodel/

以下是传入的模型对象的结构。

alt text

想要在qml内使用模型对象的成员,必须按以下格式定义:

alt text

这种方法,其实类似QStringList(QList的元素是QString),都是不能更改数据就自动更新UI界面

3 QAbstractItemModel

QAbstractItemModel 类定义了item模型必须使用的标准接口,该类不应该被直接实例化,而应该通过子类化创建新的模型。

  • QListView 应该考虑使用继承 QAbstractListModel 的模型。

  • QTableView 应该考虑使用继承 QAbstractTableModel 的模型。

3.1 QAbstractListModel

该部分示例程序参考 /assets/Qt6/qml_20_models/abstractitemmodel/

子类继承 QAbstractListModel 必须要实现以下三个虚函数

int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
virtual QHash<int, QByteArray> roleNames() const;

如果要实现数据的插入、删除、移动等方法,具体先调用以下函数:

1)整体更新
void beginResetModel();
void endResetModel();

2)插入时触发行更新
beginInsertRows(QModelIndex(), pos, pos);
endInsertRows();

3)移除行后的更新
void beginRemoveRows(const QModelIndex &parent, int first, int last);
void endRemoveRows();

4)移动行后的更新
bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationRow);
void endMoveRows();

5)具体的行更新
QModelIndex modelIndex = this->index(indexItem, 0, QModelIndex()); //其中indexItem为要更新的行索引 
emit this->dataChanged(modelIndex, modelIndex); 

4 ListModel例子

ListModel 例子可以参考 /assets/Qt6/qml_20_models/DecoratingViews.qml

alt text

参考

参考1:Using C++ Models with Qt Quick Views

参考2:QML之QAstractListModel使用案列