以下是一个示例程序,演示了如何使用 QSortFilterProxyModel 对 QTableView 进行过滤和排序,并在双击单元格时编辑过滤后的数据:
main.cpp
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建源模型
QStringList headers = {"Name", "Age"};
QList<QList<QVariant>> data = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35},
{"David", 40}
};
QStandardItemModel sourceModel(data.size(), headers.size());
sourceModel.setHorizontalHeaderLabels(headers);
for (int i = 0; i < data.size(); ++i) {
for (int j = 0; j < data[i].size(); ++j) {
sourceModel.setData(sourceModel.index(i, j), data[i][j]);
}
}
// 创建代理模型
QSortFilterProxyModel proxyModel;
proxyModel.setSourceModel(&sourceModel);
// 创建表格视图
QTableView tableView;
tableView.setModel(&proxyModel);
tableView.setSortingEnabled(true); // 允许排序
tableView.setSelectionBehavior(QAbstractItemView::SelectRows);
// 双击单元格开始编辑
QObject::connect(&tableView, &QTableView::doubleClicked, [&](const QModelIndex& index) {
if (index.isValid()) {
QModelIndex sourceIndex = proxyModel.mapToSource(index);
if (sourceIndex.isValid()) {
tableView.edit(sourceIndex);
}
}
});
// 创建窗口
QWidget window;
QVBoxLayout layout(&window);
layout.addWidget(&tableView);
window.show();
return app.exec();
}
本示例程序创建了一个包含姓名和年龄两列的表格,使用 QStandardItemModel 作为源模型,然后创建了一个 QSortFilterProxyModel 代理模型,并将其设置为表格视图的模型。在双击单元格时,会通过 mapToSource() 函数将代理模型中的索引映射到源模型中的索引,并调用 tableView.edit() 函数开始编辑源模型中的数据。
运行程序后,可以看到表格中显示的是源模型中的所有数据。可以通过在代理模型中设置过滤条件来对数据进行过滤,例如只显示年龄大于等于 30 的行:
proxyModel.setFilterKeyColumn(1); // 根据第二列过滤
proxyModel.setFilterMinimumValue(30); // 年龄 >= 30
还可以通过在代理模型中设置排序规则来对数据进行排序,例如按照姓名排序:
proxyModel.setSortRole(Qt::DisplayRole); // 排序依据为显示值
proxyModel.sort(proxyModel.columnCount() - 2, Qt::AscendingOrder); // 按照第一列升序排列
这里使用 columnCount() - 2 来获取第一列的索引,因为最后一列是年龄,不参与排序。
完整代码可以在 https://github.com/qt-studio/qsortfilterproxymodel-example 中找到。