QTableView的筛选和排序实现

类介绍

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;
    }
}
  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zw_ggr_2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值