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

这篇具有很好参考价值的文章主要介绍了Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、效果示例图

1.1 自定义表格排序示例图

本文过滤条件为行索引取余2等于0时返回true,且从下图中可以看到,奇偶行是各自挨在一起的。
Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)

1.2 自定义表格过滤示例图

下图添加两列条件(当前数据大于当前列条件才返回true,且多个列条件为且关系);下方添加条件分别为,”0列,条件值50“,”2列条件值40“,综合下来为0列值大于50且2列值大于40则返回true
Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)

二、相关理解

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

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

三、源码

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include "CSortFilterProxyModel.h"

#include <QMainWindow>
#include <QStandardItemModel>

namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit CMainWindow(QWidget *parent = nullptr);
    ~CMainWindow();

private slots:
    /**
     * @brief on_btnCustom_clicked 自定义条件添加响应函数
     */
    void on_btnCustom_clicked();

    /**
     * @brief on_btnInitData_clicked 数据初始化响应函数
     */
    void on_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;
}

void CMainWindow::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("");
}

void CMainWindow::on_btnInitData_clicked()
{
    // 虽然表格上是过滤模型,但是数据还是得设置到数据模型上才可
    for(int row = 0; row != 10; ++row)
    {
        for(int col = 0; col != 10; ++col)
        {
            // 设置当前行列的item, 并初始化随机值
            m_model->setItem(row, col, new QStandardItem(QString::number(rand() % 100)));
        }
    }
}

CMainWindow.ui

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

CSortFilterProxyModel.h

#ifndef CSORTFILTERPROXYMODEL_H
#define CSORTFILTERPROXYMODEL_H

#include <QSortFilterProxyModel>

class CSortFilterProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT
public:
    explicit CSortFilterProxyModel(QObject *parent = nullptr);

    /**
     * @brief appendCondition 追加条件函数
     * @param col 条件列
     * @param val 条件值
     */
    void appendCondition(int col, int val);

    // QSortFilterProxyModel interface
protected:
    /**
     * @brief filterAcceptsRow 过滤行函数
     * @param source_row 当前行索引
     * @param source_parent 当前行父对象(没有则为空)
     * @return 过滤结果
     */
    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;

    /**
     * @brief lessThan 排序函数
     * @param source_left 比较的左值
     * @param source_right 比较的右值
     * @return 比较结果
     */
    bool lessThan(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)
{

}

void CSortFilterProxyModel::appendCondition(int col, int val)
{
    // 直接赋值(不存在会添加,已存在会更新)
    m_mapFilterCondition[col] = val;
}

bool CSortFilterProxyModel::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;
}

bool CSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    // 当前行为取余2等于0时返回true(就是说默认降序排序偶数行在前)
    return 0 == source_left.row() % 2;
}

总结

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

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

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除文章来源地址https://www.toymoban.com/news/detail-447972.html

到了这里,关于Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt创建右键菜单的两种通用方法(QTableView实现右键菜单,含源码+注释)

    下图为两种右键菜单实现的示例图,源码在本文第三节(源码含详细注释)。 提示:不会使用Qt设计师设计界面的小伙伴点击这里。 该方法是触发contextMenuEvent事件来实现右键菜单,只需在该事件函数中写入对应的右键菜单代码即可。 该方法是通过控件发出的customContextMenuR

    2024年02月15日
    浏览(50)
  • PHP elasticsearch 条件过滤、排序、高亮实现

    php在做搜索引擎时,进程要对结果进行筛选,所以我们这里记录一下elasticsearch 条件过滤、排序、高亮实现。在创建索引时如果使用了mapping映射,请将要过滤和排序的字段index设置为true ok,搞定! php写搜索时注意:多个筛选条件时,term、range外面还有一层[],高亮需指定字段,

    2023年04月21日
    浏览(37)
  • Qt QTableView滑动、居中、选中加粗

    目录 1.效果: 2.滑动 3.居中 4.选中加粗 5.使用的样式表   在使用触控屏时需要列表或视图能够滑动查看 为滚动区域注册了 鼠标左键的手势识别器,在触摸屏上时可以设置为 QScroller::TouchGesture 触摸手势,很多view都可以实现滑动:QListView,QComboBox下拉框滑动... 也可以自己配置

    2024年02月11日
    浏览(37)
  • 【QT 基础教程 十四】QTableView类解析

    头文件:#includeQTableView 模块:QT += widgets 父类:QAbstractItemView 功能:Qt中的QTableView可以将数据项显示在表格视图中 1.初始化 2.绑定模型 3.添加内容显示 视图是模型的界面显示 ,所以在视图显示内容,需要让模型拿到数据。 4.隐藏行 5.设置行高、列宽 6.获取选中行 7.返回当前

    2024年03月20日
    浏览(72)
  • QT中QTableView对单个单元格操作的方法

    此处举例对单元格操作的读取和写入

    2024年02月16日
    浏览(40)
  • Qt之QTableView显示鼠标悬浮下的项的信息

            业务上遇到一些需求,某个需求是当鼠标移动到QTableView的item上时,显示该item的某些信息。首先想到的思路就是鼠标悬浮事件,即安装QTableView的事件过滤器,然后在eventFilter进行判断即可。实现很简单,主要在针对qt界面处理子界面的事件响应时,主要是还没搞清

    2024年02月13日
    浏览(47)
  • Qt QtableWidget、QtableView表格删除选中行、删除单行、删除多行

    设置 操作 设置 操作 无需设置 setSelectionBehavior(QAbstractItemView::SelectRows) ,但是可以选择的那一列最好设置为不可编辑。按下Ctrl键,选择多行。 设置1 设置2 操作 QTableWidgetSelectionRange是Qt框架中用于表示QTableWidget中选定的一块单元格区域的类。以下是如何使用QTableWidgetSelectionR

    2024年02月01日
    浏览(51)
  • Qt 获得QTableview所选中的行的某一列数据

    1、点击QtableView控件-》右键-》跳到槽-》选择 2、编写槽函数信息  备注:由于信息保密,我把类名用XXX代替了

    2024年02月16日
    浏览(46)
  • SpringBoot3整合SpringSecurity,实现自定义接口权限过滤

    接口权限过滤是指对于某些接口或功能,系统通过设定一定的权限规则,只允许经过身份认证且拥有相应权限的用户或应用程序进行访问和操作 。这种技术可以有效地保护系统资源和数据安全,防止未授权的用户或程序进行恶意操作或非法访问。通常情况下,接口权限过滤需

    2024年02月08日
    浏览(53)
  • QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解

    目录 一、Qt 项目视图(Item Views)         1.QListView 2.QTreeView 3.QTableView 二、Qt 项目部件(Item Widgets) 1.QListWidget 2.QTreeWidget 3.QTableWidget 一、Qt 项目视图(Item Views)          控件名称依次解释如下: List View:清单视图 Tree View: 树视图 Table View:表视图 Column View: 列视图 Undo Vie

    2024年01月20日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包