0


Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)

文章目录

一、效果示例图

1.1 自定义表格排序示例图

本文过滤条件为行索引取余2等于0时返回true,且从下图中可以看到,奇偶行是各自挨在一起的。
在这里插入图片描述

1.2 自定义表格过滤示例图

下图添加两列条件(当前数据大于当前列条件才返回true,且多个列条件为且关系);下方添加条件分别为,”0列,条件值50“,”2列条件值40“,综合下来为0列值大于50且2列值大于40则返回true
在这里插入图片描述

二、相关理解

被动触发:不论是排序还是过滤,都会在添加数据的时候触发自定义排序/过滤函数;
主动触发:排序,可通过数据模型或过滤模型的sort函数触发;过滤,可通过setFilterRegExp函数触发。(此处说的两个函数主动调用后会运行自定义排序/过滤条件,前提是对应的函数有重写)

过滤:此外,除开本文写的filterAcceptsRow函数还有filterAcceptsColumn函数,其触发条件与filterAcceptsRow一致

三、源码

CMainWindow.h

#ifndefCMAINWINDOW_H#defineCMAINWINDOW_H#include"CSortFilterProxyModel.h"#include<QMainWindow>#include<QStandardItemModel>namespace Ui {classCMainWindow;}classCMainWindow:publicQMainWindow{
    Q_OBJECT

public:explicitCMainWindow(QWidget *parent =nullptr);~CMainWindow();private slots:/**
     * @brief on_btnCustom_clicked 自定义条件添加响应函数
     */voidon_btnCustom_clicked();/**
     * @brief on_btnInitData_clicked 数据初始化响应函数
     */voidon_btnInitData_clicked();private:
    Ui::CMainWindow         *ui;

    QStandardItemModel      *m_model;// 数据模型

    CSortFilterProxyModel   *m_customFilterModel;// 自定义过滤器模型};#endif// CMAINWINDOW_H

CMainWindow.cpp

#include"CMainWindow.h"#include"ui_CMainWindow.h"#include<QMessageBox>CMainWindow::CMainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::CMainWindow){
    ui->setupUi(this);// 数据模型对象创建
    m_model =new QStandardItemModel;// 自定义过滤器类对象创建
    m_customFilterModel =new CSortFilterProxyModel;// 设置数据源模型
    m_customFilterModel->setSourceModel(m_model);// 先将正常数据模型类设置到表格中
    ui->tableView->setModel(m_customFilterModel);// 设置表格可排序(设置过后通过自定义lessThan函数排序)
    ui->tableView->setSortingEnabled(true);}CMainWindow::~CMainWindow(){// 释放内存空间delete m_customFilterModel;delete m_model;delete ui;}voidCMainWindow::on_btnCustom_clicked(){// 获取条件字符串
    QString colStr = ui->editCol->text();
    QString conditionStr = ui->editCondition->text();if(colStr.isEmpty()|| conditionStr.isEmpty()){QMessageBox::information(this,"提示","条件值为空,请输入条件");return;}// 获取条件并将其添加到自定义模型中
    m_customFilterModel->appendCondition(ui->editCol->text().toInt(), ui->editCondition->text().toInt());// 条件列和条件值编辑框清空
    ui->editCol->clear();
    ui->editCondition->clear();// 通过设置过滤条件触发自定义过滤(此处条件不会影响自定义过滤)
    m_customFilterModel->setFilterRegExp("");}voidCMainWindow::on_btnInitData_clicked(){// 虽然表格上是过滤模型,但是数据还是得设置到数据模型上才可for(int row =0; row !=10;++row){for(int col =0; col !=10;++col){// 设置当前行列的item, 并初始化随机值
            m_model->setItem(row, col,newQStandardItem(QString::number(rand()%100)));}}}

CMainWindow.ui

<?xml version="1.0" encoding="UTF-8"?><uiversion="4.0"><class>CMainWindow</class><widgetclass="QMainWindow"name="CMainWindow"><propertyname="geometry"><rect><x>0</x><y>0</y><width>821</width><height>525</height></rect></property><propertyname="windowTitle"><string>CMainWindow</string></property><widgetclass="QWidget"name="centralWidget"><layoutclass="QGridLayout"name="gridLayout"><itemrow="2"column="1"><widgetclass="QLineEdit"name="editCondition"><propertyname="text"><string/></property><propertyname="placeholderText"><string>条件值</string></property></widget></item><itemrow="2"column="0"><widgetclass="QLineEdit"name="editCol"><propertyname="text"><string/></property><propertyname="placeholderText"><string>列</string></property></widget></item><itemrow="4"column="0"colspan="3"><widgetclass="QTableView"name="tableView"/></item><itemrow="1"column="0"><widgetclass="QPushButton"name="btnInitData"><propertyname="text"><string>初始化数据</string></property></widget></item><itemrow="1"column="1"><widgetclass="QPushButton"name="btnCustom"><propertyname="text"><string>添加自定义模型条件</string></property></widget></item></layout></widget><widgetclass="QMenuBar"name="menuBar"><propertyname="geometry"><rect><x>0</x><y>0</y><width>821</width><height>23</height></rect></property></widget><widgetclass="QToolBar"name="mainToolBar"><attributename="toolBarArea"><enum>TopToolBarArea</enum></attribute><attributename="toolBarBreak"><bool>false</bool></attribute></widget><widgetclass="QStatusBar"name="statusBar"/></widget><layoutdefaultspacing="6"margin="11"/><resources/><connections/></ui>

CSortFilterProxyModel.h

#ifndefCSORTFILTERPROXYMODEL_H#defineCSORTFILTERPROXYMODEL_H#include<QSortFilterProxyModel>classCSortFilterProxyModel:publicQSortFilterProxyModel{
    Q_OBJECT
public:explicitCSortFilterProxyModel(QObject *parent =nullptr);/**
     * @brief appendCondition 追加条件函数
     * @param col 条件列
     * @param val 条件值
     */voidappendCondition(int col,int val);// QSortFilterProxyModel interfaceprotected:/**
     * @brief filterAcceptsRow 过滤行函数
     * @param source_row 当前行索引
     * @param source_parent 当前行父对象(没有则为空)
     * @return 过滤结果
     */boolfilterAcceptsRow(int source_row,const QModelIndex &source_parent)const;/**
     * @brief lessThan 排序函数
     * @param source_left 比较的左值
     * @param source_right 比较的右值
     * @return 比较结果
     */boollessThan(const QModelIndex &source_left,const QModelIndex &source_right)const;private:
    QMap<int,int>  m_mapFilterCondition;// 条件值保存容器<列, 条件值>};#endif// CSORTFILTERPROXYMODEL_H

CSortFilterProxyModel.cpp

#include"CSortFilterProxyModel.h"#include<QDebug>#include<QStandardItemModel>CSortFilterProxyModel::CSortFilterProxyModel(QObject *parent):QSortFilterProxyModel(parent){}voidCSortFilterProxyModel::appendCondition(int col,int val){// 直接赋值(不存在会添加,已存在会更新)
    m_mapFilterCondition[col]= val;}boolCSortFilterProxyModel::filterAcceptsRow(int source_row,const QModelIndex &source_parent)const{// 定义返回值变量bool ret =true;// 获取数据源模型对象,并转换为需要的类型模板
    QStandardItemModel *srcModel =dynamic_cast<QStandardItemModel *>(sourceModel());if(nullptr!= srcModel){foreach(int col, m_mapFilterCondition.keys()){// 获取当前的item对象
            QStandardItem *item = srcModel->item(source_row, col);// 此时对应item不为空且整形值要小于条件值才显示if(nullptr!= item && m_mapFilterCondition[col]> item->text().toInt()){
                ret =false;break;}}}return ret;}boolCSortFilterProxyModel::lessThan(const QModelIndex &source_left,const QModelIndex &source_right)const{// 当前行为取余2等于0时返回true(就是说默认降序排序偶数行在前)return0== source_left.row()%2;}

总结

虽然自定义排序和过滤比较简单,但是在项目中非常实用,如需要将某行/列置顶,特殊条件过滤等。

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/wj584652425/article/details/129252618
版权归原作者 lw向北. 所有, 如有侵权,请联系我们删除。

“Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)”的评论:

还没有评论