Qt的所有模型类都是基于QAbstractItemModel虚类,这个定义了接口,可以供视图和代理来访问数据。
QStringListModel | 存储一个字符串列表 |
QStandardItemModel | 存储任意的分层次的数据 |
QDirModel | 封装本地文件系统 |
QSqlQueryModel | 封装一个SQL结果集 |
QSqlTableModel | 封装一个SQL表 |
QSqlRelationalTableModel | 利用外键封装一个SQL表 |
QSortFilterProxyModel | 排序、筛选另一个模型 |
如果Qt提供的这些标准模型无法满足需要,还可以子类化QAbstractItemModel、QAbstractListModel或者QAbstractTableModel来创建自定义的模型。
1.QStringListModel:
QStringList leaders{"Shakey","The Brow","Shoulders"};
QStringListModel *model = new QStringListModel(this);
model.setStringList(leaders);
QListView *listView = new QListView; // 默认只读属性
listView->setModel(model);
// 允许用户简单地通过开始输入或者双击进入编辑字符串的状态
listView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked);
// eg 插入,模型会自动更新列表视图
int row = listView->currentIndex().row();// 获取当前选中项是第几行
model->insertRows(row, 3); // 在当前行插入新3行,以前的行向后推移
// 模型中的每一个数据项都对应一个模型索引
QModelIndex index = model->index(row);
listView->setCurrentIndex(index);// 设置当前行
listView->edit(index); // 设置当前行进入编辑的状态
// eg 删除2行
model->removeRows(listView->currentIndex().row(), 2);
QStringList list = model->stringList();
2.QDirModel:
该模型封装了计算机的文件系统并且可以显示或者隐藏不同的文件属性。
//---1 构造QDirModel
QDirModel *model = new QDirModel;
model->setReadOnly(false);
model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name); // 排序类别
//---2 构造QTreeView和绑定model
QTreeView *treeView = new QTreeView;
treeView->setModel(model);
treeView->header()->setStretchLastSection(true);
treeView->header()->setSectionsClickable(true);
treeView->header()->setSortIndicator(0, Qt::AscendingOrder); // 排序
treeView->header()->setSortIndicatorShown(true);
//---3 通过QModelIndex操作
QModelIndex index = model->index(QDir::currentPath());
treeView->expand(index);// 展开
treeView->scrollTo(index);// 滚动至当前项
treeView->resizeColumnToContents(0);// 确保首列足够宽,不使用省略号
//----eg 添加子目录
QModelIndex index = treeView->currentIndex();
if (index.isValid()) {
QString dirName = QInputDialog::getText(this, "Create Dir", "Dir Name");
if (!dirName.isEmpty()) {
model->mkdir(index, dirName);
} // 在当前目录下用dirName创建子目
}
//----eg 删除子目或文件
QModelIndex index = treeView->currentIndex();
if (index.isValid()) {
if (model->fileInfo(index).isDir()) {
model->rmdir(index); // 删除子目
} else {
model->remove(index); } // 删除文件
}
QDir也可以完成文件或子目的删除操作。
3.QSortFilterProxyModel:
该模型封装了一个已经存在的模型并且对在底层模型和视图之间的传递的数据进行操作。
// ---1 构建资源model
QStringListModel *sourceModel = new QStringListModel(this);
sourceModel->setStringList(QColor::colorNames());
// ---2 构建过滤proxyModel
QSortFilterProxyModel* proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel);
proxyModel->setFilterKeyColumn(0);
// ---3 构建显示列表
QListView *listView = new QListView;
listView->setModel(proxyModel);
// ---4 构建过滤类型comboBox
QComboBox *syntaxComboBox = new QComboBox;
syntaxComboBox->addItem("Regular expression", QRegExp::RegExp);
syntaxComboBox->addItem("Wildcard", QRegExp::Wildcard);
syntaxComboBox->addItem("Fixed string", QRegExp::FixedString);
// ---5 获取使用正则表达式QRegExp的语法模式
QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(syntaxComboBox->itemData(syntaxComboBox->currentIndex().toInt()));
// ---6 创建正则表达式,并过滤
QRegExp regExp(filterLineEdit->text(), Qt::CaseInsensitive, syntax);
proxyModel->setFilterRegExp(regExp);
setSourceModel()传递底层模型并且告诉这个代理过滤器被应用在初始模型的第0列。
改变过滤器字符串或者模式语法组合,通过QRegExp正则表达式过滤查询,并调用setFilterRegExp,激活新的过滤器并会自动更新视图。