QSortFilterProxyModel是Qt框架中的代理模型,用于对其他模型进行排序和筛选。它可以处理源模型的数据,提供排序和自定义筛选功能,同时保持视图与源模型解耦。用户可以通过设置筛选条件、排序规则来定制数据展示,并使用接口如setSourceModel、sort、setFilterRegExp等进行操作。
摘要由CSDN通过智能技术生成
QSortFilterProxyModel是Qt框架中的一个模型类,用于对其他模型进行排序和筛选操作。它是QAbstractProxyModel的子类,可以被用作Qt中的Model/View架构中的中间层。
QSortFilterProxyModel提供了以下功能:
-
排序(Sorting):QSortFilterProxyModel可以根据指定的一列或多列对源模型(原始模型)的数据进行排序。它可以以升序或降序的方式对模型数据进行排序,并将排序后的数据展示给视图(例如QTableView)。
-
筛选(Filtering):QSortFilterProxyModel可以根据指定的条件对源模型的数据进行筛选,只显示满足条件的数据。你可以通过实现自定义的filterAcceptsRow()函数来定义筛选条件。
-
模型索引映射(Model Index Mapping):QSortFilterProxyModel会为源模型和视图之间的索引提供映射。这意味着在视图层中使用QSortFilterProxyModel的索引进行操作时,可以方便地转换为对源模型的索引进行操作。
通过将QSortFilterProxyModel与视图和源模型连接起来,可以有效地对源模型中的数据进行排序和筛选操作,同时保持视图与源模型的解耦。
需要注意的是,QSortFilterProxyModel并不是一个真正的数据模型,它本身是一个代理模型,只是对源模型的数据进行了处理和过滤。因此,在使用QSortFilterProxyModel时,需要确保设置好源模型并正确设置筛选条件和排序规则。
你可以通过Qt文档详细了解QSortFilterProxyModel类的更多用法、函数和信号。
常用的接口
以下是QSortFilterProxyModel类的一些主要接口:
-
setSourceModel(QAbstractItemModel *sourceModel):设置QSortFilterProxyModel的源模型,即需要进行排序和筛选的原始数据模型。
-
sort(int column, Qt::SortOrder order = Qt::AscendingOrder):对源模型的数据进行排序。通过指定列索引和排序顺序(升序或降序),对源模型数据进行排序。
-
filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent):用于自定义筛选的函数。根据指定的条件判断是否接受某行数据,返回true表示接受,false表示过滤掉。
-
setFilterRegExp(const QRegularExpression ®Exp):设置用于筛选的正则表达式。只有与正则表达式匹配的数据才会被显示。
-
setFilterKeyColumn(int column):设置用于筛选的列索引。只有指定列中的数据会被筛选出来。
-
mapToSource(const QModelIndex &proxyIndex):将代理模型(QSortFilterProxyModel)中的索引映射到源模型(source model)中的索引。
-
mapFromSource(const QModelIndex &sourceIndex):将源模型中的索引映射到代理模型中的索引。
-
setDynamicSortFilter(bool enable):设置是否启用动态排序和筛选。如果启用,则每次源模型数据变化时重新排序和筛选。
-
sortRole():返回当前排序时使用的角色。
-
setSortRole(int role):设置用于排序的角色。默认情况下,使用DisplayRole进行排序。
-
filterRole():返回当前筛选时使用的角色。
-
setFilterRole(int role):设置用于筛选的角色。默认情况下,使用DisplayRole进行筛选。
-
filterCaseSensitivity():返回筛选时是否区分大小写。
-
setFilterCaseSensitivity(Qt::CaseSensitivity caseSensitivity):设置筛选时是否区分大小写。
-
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
Qt之 QTableWidget 列排序
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