QSortFilterProxyModel是Qt框架中的代理模型,用于对其他模型进行排序和筛选。它可以处理源模型的数据,提供排序和自定义筛选功能,同时保持视图与源模型解耦。用户可以通过设置筛选条件、排序规则来定制数据展示,并使用接口如setSourceModel、sort、setFilterRegExp等进行操作。 摘要由CSDN通过智能技术生成

QSortFilterProxyModel是Qt框架中的一个模型类,用于对其他模型进行排序和筛选操作。它是QAbstractProxyModel的子类,可以被用作Qt中的Model/View架构中的中间层。

QSortFilterProxyModel提供了以下功能:

  1. 排序(Sorting):QSortFilterProxyModel可以根据指定的一列或多列对源模型(原始模型)的数据进行排序。它可以以升序或降序的方式对模型数据进行排序,并将排序后的数据展示给视图(例如QTableView)。

  2. 筛选(Filtering):QSortFilterProxyModel可以根据指定的条件对源模型的数据进行筛选,只显示满足条件的数据。你可以通过实现自定义的filterAcceptsRow()函数来定义筛选条件。

  3. 模型索引映射(Model Index Mapping):QSortFilterProxyModel会为源模型和视图之间的索引提供映射。这意味着在视图层中使用QSortFilterProxyModel的索引进行操作时,可以方便地转换为对源模型的索引进行操作。

通过将QSortFilterProxyModel与视图和源模型连接起来,可以有效地对源模型中的数据进行排序和筛选操作,同时保持视图与源模型的解耦。

需要注意的是,QSortFilterProxyModel并不是一个真正的数据模型,它本身是一个代理模型,只是对源模型的数据进行了处理和过滤。因此,在使用QSortFilterProxyModel时,需要确保设置好源模型并正确设置筛选条件和排序规则。

你可以通过Qt文档详细了解QSortFilterProxyModel类的更多用法、函数和信号。

常用的接口

以下是QSortFilterProxyModel类的一些主要接口:

  1. setSourceModel(QAbstractItemModel *sourceModel):设置QSortFilterProxyModel的源模型,即需要进行排序和筛选的原始数据模型。

  2. sort(int column, Qt::SortOrder order = Qt::AscendingOrder):对源模型的数据进行排序。通过指定列索引和排序顺序(升序或降序),对源模型数据进行排序。

  3. filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent):用于自定义筛选的函数。根据指定的条件判断是否接受某行数据,返回true表示接受,false表示过滤掉。

  4. setFilterRegExp(const QRegularExpression &regExp):设置用于筛选的正则表达式。只有与正则表达式匹配的数据才会被显示。

  5. setFilterKeyColumn(int column):设置用于筛选的列索引。只有指定列中的数据会被筛选出来。

  6. mapToSource(const QModelIndex &proxyIndex):将代理模型(QSortFilterProxyModel)中的索引映射到源模型(source model)中的索引。

  7. mapFromSource(const QModelIndex &sourceIndex):将源模型中的索引映射到代理模型中的索引。

  8. setDynamicSortFilter(bool enable):设置是否启用动态排序和筛选。如果启用,则每次源模型数据变化时重新排序和筛选。

  9. sortRole():返回当前排序时使用的角色。

  10. setSortRole(int role):设置用于排序的角色。默认情况下,使用DisplayRole进行排序。

  11. filterRole():返回当前筛选时使用的角色。

  12. setFilterRole(int role):设置用于筛选的角色。默认情况下,使用DisplayRole进行筛选。

  13. filterCaseSensitivity():返回筛选时是否区分大小写。

  14. setFilterCaseSensitivity(Qt::CaseSensitivity caseSensitivity):设置筛选时是否区分大小写。

  15. invalidate():使代理模型无效,导致重新构建索引映射。

以上仅为QSortFilterProxyModel类的一部分接口,还有其他接口可用于更高级的排序和筛选操作。详细了解每个接口的作用以及使用方式,请参考Qt文档。

在这个示例程序中,创建了一个QTableView和一个QStandardItemModel,将数据添加到模型中,并将模型设置为表格视图的模型。

创建了一个QLineEdit,用于输入筛选条件。当用户输入筛选条件时,通过QSortFilterProxyModel过滤器,实现筛选数据。

当用户选择一行时,使用QModelIndex获取选中行的数据,并输出到控制台。

创建了一个QComboBox,用于选择排序条件,通过QSortFilterProxyModel过滤器,实现数据的排序。

以下是代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTableView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QLineEdit>
#include <QPushButton>
#include <QComboBox>
#include <QModelIndex>
class MainWindow : public QMainWindow
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    QTableView *tableView;
    QStandardItemModel *model;
    QLineEdit *lineEdit;
    QPushButton *pushButton;
    QSortFilterProxyModel *proxyModel;
private slots:
    void filterData(const QString &text);
    void onButtonClicked();
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHeaderView>
#include <QSortFilterProxyModel>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    // 创建表格视图和模型
    tableView = new QTableView(this);
    model = new QStandardItemModel(this);
    model->setColumnCount(2);
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Age"));
    // 添加数据
    QList<QStandardItem*> row1 = {new QStandardItem("Alice"), new QStandardItem("25")};
    QList<QStandardItem*> row2 = {new QStandardItem("Bob"), new QStandardItem("20")};
    QList<QStandardItem*> row3 = {new QStandardItem("Charlie"), new QStandardItem("35")};
    QList<QStandardItem*> row4 = {new QStandardItem("David"), new QStandardItem("30")};
    QList<QStandardItem*> row5 = {new QStandardItem("Eve"), new QStandardItem("40")};
    model->appendRow(row1);
    model->appendRow(row2);
    model->appendRow(row3);
    model->appendRow(row4);
    model->appendRow(row5);
    // 设置表格视图的模型
    tableView->setModel(model);
    // 设置表格视图的选择模式为单选
    //tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    // 设置表格视图的选择行为为选择一整行
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    // 设置表格视图的列宽自适应
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    // 创建筛选框
    lineEdit = new QLineEdit(this);
    //创建排序和过滤代理
    proxyModel = new QSortFilterProxyModel(this);
    //创建操作按钮
    pushButton = new QPushButton("打印选中行",this);
    //创建排序下拉框
    QComboBox *comboBox = new QComboBox(this);
    comboBox->addItem("Name");
    comboBox->addItem("Age");
    //创建布局,并将表格视图和筛选框添加到布局中
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(tableView);
    layout->addWidget(lineEdit);
    layout->addWidget(pushButton);
    layout->addWidget(comboBox);
    // 创建主窗口的中心部件,并设置布局
    QWidget *centralWidget = new QWidget(this);
    centralWidget->setLayout(layout);
    setCentralWidget(centralWidget);
    // 连接筛选框的textChanged信号和filterData槽函数
    connect(lineEdit, &QLineEdit::textChanged, this, &MainWindow::filterData);
    // 连接操作按钮和它的槽函数
    connect(pushButton, &QPushButton::clicked, this, &MainWindow::onButtonClicked);
    // 连接排序下拉框和它的槽函数
    connect(comboBox, QOverload<int>::of(&QComboBox::activated), [=](int index){
        if (index == 0) {
            proxyModel->sort(0, Qt::AscendingOrder);
        } else if (index == 1) {
            proxyModel->sort(1, Qt::AscendingOrder);
    //初始化时设置空字符串作为筛选模型
    filterData("");
MainWindow::~MainWindow()
void MainWindow::filterData(const QString &text)
    // 创建过滤器
    proxyModel->setSourceModel(model);
    // 设置过滤规则
    proxyModel->setFilterRegExp(QRegExp(text, Qt::CaseInsensitive, QRegExp::FixedString));
    proxyModel->setFilterKeyColumn(0);
    // 设置表格视图的模型为过滤器
    tableView->setModel(proxyModel);
void MainWindow::onButtonClicked()
    // 获取QSortFilterProxyModel的选择模型
    QItemSelectionModel *selectionModel = tableView->selectionModel();
    // 获取当前选中的行
    QModelIndexList selectedRows = selectionModel->selectedRows();
    // 遍历选中的行
    foreach (QModelIndex index, selectedRows) {
        //处理选中的行 方法一
        QString name = proxyModel->index(index.row(), 0).data().toString();
        QString age = proxyModel->index(index.row(), 1).data().toString();
        qDebug() << "Selected: " << name << ", " << age;
        //处理选中的行 方法二
        QModelIndex sourceIndex = proxyModel->mapToSource(index);
        name = model->index(sourceIndex.row(), 0).data().toString();
        age = model->index(sourceIndex.row(), 1).data().toString();
        qDebug() << "Selected: " << name << ", " << age;
				
今日,由于工作需要,要实现QTableView中点击表头进行排序的功能,但QTableView中并未提供此功能,经过苦苦的网络搜索也为发现可用的代码。最后经过跟踪QTableWidget的排序功能实现,总算实现了此功能。 此文章将使用QT源码中自带的例子做为基础: (file source: examples/widgets/tutorials/modelview/4_headers/main
关于Qt QTableView表格排序的问题 本人用到的方法是setSortEnable,发下针对某一列排序失败,后来发现该列值虽然显示为数字,但是实际存储的是字符串,所以table会按照字符串来排序,后来查阅相关资料,发现需要改写排序方法,本人是个懒人,于是在向表格内插入数据之前,便做是否为数字的判断,如果是,则按照插入数字的规则向表格内插入数据,然后问题解决了,如果有会改写方法的朋友,不妨一起交了,不胜感激! //QTableView model->lgoods_model view->lgoods_view lgoods_head_view = lgoods_view->horizontalHeader(); lgoods_head_view->setSortIndic...
开发修理登记软件时,需要在tableview中的表头实现筛选功能 代码如下: 第一步重写 QHeaderView,网上有一种方法也是重写,然后在paintSection函数中指定位置大小,非常方便,不需要跟着状态进行改变。但是不能根据列数进行创建。 因为在创建之前不清楚总共有多少列,找了一个折中的办法,就是创建时指定有多少列,也存在一个问题,tableView中列数可以配置,程序初建了一个最多的,当列数减少之后,多余的隐藏,同时在改变大小等情况下,都需要重新指定筛选按钮的位置。 #include <Q
QtQTableWidget 列排序 1、常规的QTableWidget的排序接口 void QTableView::setSortingEnabled(bool enable) // 允许点击表头进行排序 void QTableWidget::sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder) // 排序接口 table->setSortingEnabled(true); // 运行排序 table-&
QTabelView sort 在QT中为了通过表格展示数据时,通常采用QTableView组件来展示。 常用的表格储存方式就是通过QStandardItemModel来进行存储 (1) 排序 Qt排序通常如果通过某列进行排序,用到sortByColumn 或者对模型model使用sort进行排序 该两种方式。 代码示例如下: self.model=QStandardItemModel() self.tableView.setModel(self.model) self.model.setIt