下面是一个使用 QSortFilterProxyModel 对 QTableView 进行数据过滤的示例程序,包含双击修改功能:
#include <QApplication>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QTableView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建源模型
QStandardItemModel sourceModel;
sourceModel.setRowCount(4);
sourceModel.setColumnCount(3);
sourceModel.setData(sourceModel.index(0, 0), "张三");
sourceModel.setData(sourceModel.index(0, 1), "男");
sourceModel.setData(sourceModel.index(0, 2), 20);
sourceModel.setData(sourceModel.index(1, 0), "李四");
sourceModel.setData(sourceModel.index(1, 1), "女");
sourceModel.setData(sourceModel.index(1, 2), 25);
sourceModel.setData(sourceModel.index(2, 0), "王五");
sourceModel.setData(sourceModel.index(2, 1), "男");
sourceModel.setData(sourceModel.index(2, 2), 30);
sourceModel.setData(sourceModel.index(3, 0), "赵六");
sourceModel.setData(sourceModel.index(3, 1), "女");
sourceModel.setData(sourceModel.index(3, 2), 35);
// 创建代理模型并设置过滤规则
QSortFilterProxyModel proxyModel;
proxyModel.setSourceModel(&sourceModel);
proxyModel.setFilterRegExp(QRegExp("女"));
// 创建表视图并设置代理模型
QTableView tableView;
tableView.setModel(&proxyModel);
// 设置双击修改
tableView.setEditTriggers(QAbstractItemView::DoubleClicked);
// 显示表视图
tableView.show();
return a.exec();
}
在上面的程序中,我们创建了一个源模型(QStandardItemModel
),并向其中添加了一些数据。然后,我们创建了一个代理模型(QSortFilterProxyModel
),并将其设置为源模型的代理模型,同时设置了一个过滤规则(只显示性别为“女”的行)。最后,我们创建了一个表视图(QTableView
),将其设置为代理模型的视图,并开启了双击修改功能。运行程序后,你会发现:
- 表视图中仅显示了性别为“女”的行;
- 双击某一单元格后,弹出了修改对话框,其中显示的是源模型的当前行数据而不是过滤后的数据。
这是因为 QSortFilterProxyModel 只是对源模型进行了过滤,而没有改变其数据内容。如果你需要在修改时更新过滤后的数据,可以连接代理模型的 dataChanged
信号,像下面这样实现:
QObject::connect(&proxyModel, &QSortFilterProxyModel::dataChanged, [&sourceModel](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
const QModelIndex index = sourceModel.index(row, topLeft.column());
sourceModel.dataChanged(index, index, roles);
}
});
这里我们通过 Lambda 表达式将代理模型的 dataChanged
信号连接到一个函数中,并在该函数中通过源模型的 dataChanged
函数更新相应数据。这样修改过的数据就会被正确地过滤显示出来了。