一、介绍
QAbstractListModel是Qt中的一个抽象模型类,通过其实现自定义模型提供数据给QML界面使用,也可以被QWidget界面使用。
它是Qt的模型/视图架构中的一个模型,被用于ListView、GridView、PathView、TableView、TreeView等控件上。
一个模型可以包含一对多行数据,在列中提供元素的数据。该模型可以被视图控件使用,让用户可以以不同的方式对数据进行查看和修改。
二、功能
QAbstractListModel负责实现获取数据、添加数据、修改数据、删除数据等操作,同时还具有以下功能:
1、数据通知机制:在更改模型数据时,通知视图(例如,QListView)进行更新。
2、可排序(排序原理类似于QSortFilterProxyModel):根据需要对模型的行进行排序。
3、可过滤:根据需要对模型的行进行过滤。
4、可分组:根据需要将模型的行分为组。
三、数据结构
QAbstractListModel中的数据结构是一个二维数组,即每个元素都是一个列表。每个列表表示一个列,每个列表中的元素表示该列的一个值。
例如有一个包含4列数据和3行数据的模型,数据如下:
1 2 3 4 a b c d 1 2 3 4
那么QAbstractListModel中的数据结构,就是一个包含4个列表的列表,每个列表中包含3个元素。
[1, a, 1] [2, b, 2] [3, c, 3] [4, d, 4]
四、实现
1、数据获取
数据获取是QAbstractListModel的主要功能,其核心函数是:data()
QVariant QAbstractListModel::data(const QModelIndex ¤t, int role = Qt::DisplayRole) const
其中:
current:表示一个模型索引,用来返回当前行和列的数据。
role:表示角色,用于指定返回哪个角色的数据。若是不指定默认值,会返回Qt::DisplayRole角色的数据。
该函数返回当前行和列的数据,可以根据角色(role)的不同返回不同角色的数据。
示例代码:
QVariant MyModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::DisplayRole || role == Qt::EditRole) { MyData data = m_dataList.at(index.row()); if (index.column() == 0) { return data.id; } else if (index.column() == 1) { return data.name; } } return QVariant(); }
上面的代码实现了数据的获取,其中包含了2列获取。
对于角色(role)的说明:
1、Qt::DisplayRole:显示该项的数据(默认的角色)。
2、Qt::EditRole:可编辑该项的数据。
3、Qt::ToolTipRole:悬停在该项上时显示的提示。
4、Qt::DecorationRole:在该项上显示的图标或装饰。
2、数据更改
数据更改是QAbstractListModel的另一个重要功能。下面给出setData()函数的另一个版本,它用于当模型中的数据发生更改时更新该索引项。
bool QAbstractListModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
其中:
index:表示一个模型索引,用来确定要更新哪个元素。
value:表示新的值。
role:表示角色,用于指定要更新哪个角色的数据。默认情况下,该函数更新Qt::EditRole角色的数据。
示例代码:
bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && role == Qt::EditRole) { int row = index.row(); MyData data = m_dataList.value(row); if (index.column() == 0) data.id = value.toString(); else if (index.column() == 1) data.name = value.toString(); else return false; m_dataList.replace(row, data); emit dataChanged(index, index, QVector() << role); return true; } return false; }
上面的代码实现了setData()的功能,实现了根据索引号进行更新。
请注意,您需要在更改模型数据后发出信号dataChanged(),以通知视图更新模型显示的数据。这个信号需要传递两个QModelIndex,表示要更新的数据的行和列。
3、数据插入和删除
数据插入和删除在QAbstractListModel中是使用insertRows()和removeRows()函数实现的。
bool QAbstractListModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) bool QAbstractListModel::removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
其中:
row:表示要插入或删除的行号。
count:表示要插入或删除的行数。
parent:表示模型中某个节点的父节点。默认情况下,该节点没有父节点,因此使用QModelIndex()。
示例代码:
bool MyModel::insertRows(int row, int count, const QModelIndex &parent) { beginInsertRows(parent, row, row + count - 1); for (int i = 0; i < count; ++i) { MyData data; data.id = ""; data.name = ""; m_dataList.insert(row, data); } endInsertRows(); return true; } bool MyModel::removeRows(int row, int count, const QModelIndex &parent) { beginRemoveRows(parent, row, row + count - 1); for (int i = 0; i < count; ++i) { m_dataList.removeAt(row); } endRemoveRows(); return true; }
上述代码演示了如何插入和删除模型中的行。
请注意,您需要在数据被插入或删除后发出信号beginInsertRows()或beginRemoveRows(),并在插入或删除数据后发出相应的结束信号。
五、总结
QAbstractListModel是Qt中模型/视图架构中的一个抽象模型类,提供了数据通知、数据获取、数据更改、数据插入和删除等功能,方便用户在QML、QWidget等界面中使用自定义的模型。
通过以上的示例代码,希望对读者能够更深入地了解QAbstractListModel的使用和实现原理。
原创文章,作者:HWEQN,如若转载,请注明出处:https://www.506064.com/n/332679.html