Qt之QSortFilterProxyModel的简单使用(QTableView搜索功能,含源码+注释)

一、QSortFilterProxyModel示例图

下图为QSortFilterProxyModel简单使用示例图,在设置过滤器模型到表对象上后,设置筛选文本/正则表达式就会自动筛选,源码在本文第三节,源码含详细注释。
在这里插入图片描述
提示:不会使用Qt设计师设计界面的小伙伴点击这里

二、QSortFilterProxyModel使用提要

  1. 使用过滤器需要指定一个数据模型(QStandardItemModel)作为数据源,并且该数据模型无需设置到表对象上;
  2. 过滤器指定好数据源后设置到表对象上即可正常使用
  3. 过滤器不指定过滤列时,默认过滤列为0列

三、源码

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>       //数据模型类
#include <QSortFilterProxyModel>    //过滤器模型

namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT

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

public slots:

private slots:
    /**
     * @brief on_findEdit_textChanged 查找编辑栏文本更新槽函数
     * @param arg1 更新文本
     */
    void on_findEdit_textChanged(const QString &arg1);

    /**
     * @brief on_filterColumnEdit_textChanged 指定搜索列编辑栏
     * @param arg1 指定列
     */
    void on_filterColumnEdit_textChanged(const QString &arg1);

private:
    Ui::CMainWindow     *ui;

    QStandardItemModel  *m_pModel;      //数据模型对象指针

    QSortFilterProxyModel *m_pFilterModel;  //过滤器模型对象指针

};

#endif // CMAINWINDOW_H

CMainWindow.cpp

#include "CMainWindow.h"
#include "ui_CMainWindow.h"

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
    //设置窗口标题
    this->setWindowTitle("QSortFilterProxyModel的简单使用");
    //设置文本框占位符文本
    ui->findEdit->setPlaceholderText("请输入查找内容(自动查找)");
    ui->filterColumnEdit->setPlaceholderText("请输入查询列(默认为第0列)");
    //设置查询列正则表达式(只能输入数字)
    ui->filterColumnEdit->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));

//===============数据模型(QStandardItemModel)===============
    //建立数据模型对象空间并指定父对象
    m_pModel = new QStandardItemModel(ui->tableView);
    //添加列标题
    m_pModel->setHorizontalHeaderLabels(QStringList() << "one" << "two"
                                        << "three" << "four");

//===============过滤器模型(QSortFilterProxyModel)===============
    //建立过滤器模型对象空间并指定父对象
    m_pFilterModel = new QSortFilterProxyModel(ui->tableView);
    //指定过滤器模型的数据源模型
    m_pFilterModel->setSourceModel(m_pModel);
    //指定初始化过滤列
    m_pFilterModel->setFilterKeyColumn(0);
    //! 将过滤器模型设置到表对象上
    //! 数据模型就单纯当过滤器模型的数据源即可
    ui->tableView->setModel(m_pFilterModel);

    //循环添加三行数据(随机赋值)
    for(int index = 0; index != 3; ++index)
    {
        m_pModel->appendRow(QList<QStandardItem *>()
                            << new QStandardItem(QString("值:%1").arg(rand() % 15))
                            << new QStandardItem(QString("值:%1").arg(rand() % 15))
                            << new QStandardItem(QString("值:%1").arg(rand() % 15))
                            << new QStandardItem(QString("值:%1").arg(rand() % 15)));
    }
}

CMainWindow::~CMainWindow()
{
    //! 析构函数:
    //! 有些小伙伴会发现我没有析构model、m_pFilterModel对象,
    //! 那是因为我在获取对象空间的时候指定了父对象,
    //! 当其父对象析构时,会先析构其子对象为指针的对象。
    delete ui;
}

void CMainWindow::on_findEdit_textChanged(const QString &arg1)
{
    //! 设置指定列查询字符串
    //! setFilterRegExp函数是应该重载函数
    //! 可以传入字符串或者正则表达式(此处传的是字符串)
    m_pFilterModel->setFilterRegExp(arg1);
}

void CMainWindow::on_filterColumnEdit_textChanged(const QString &arg1)
{
    //获取列编辑栏中的文本
    QString column = ui->filterColumnEdit->text();
    //判断是否为空和是否大于当前总列数
    if(column.isEmpty() || column.toInt() >= m_pModel->columnCount())
    {
        //当指定列值为空和大于当前总列数,将查找列设置为0列
        m_pFilterModel->setFilterKeyColumn(0);
    }
    else
    {
        //当指定列值正常,则设置查询列
        m_pFilterModel->setFilterKeyColumn(column.toInt());
    }
}

四、拓展

1.获取过滤器当前选中的文本

获取文本比较简单,步骤如下:

  1. 通过表对象的点击事件能拿到点击位置的QModelIndex对象
  2. 使用转到槽/自定义槽函数+链接信号槽接收点击信号发出的QModelIndex对象
  3. 在槽函数中实现获取当前选中的文本
void CMainWindow::on_tableView_clicked(const QModelIndex &index)
{
    m_text = m_pFilterModel->data(index).toString();
}

2.修改当前选中item的文本

修改item文本,首先需要获取到item对象,方法和获取文本一样都需要接收发出点击信号和参数,但槽函数内容如下:

  1. 存放当前点击对象的item指针,在.h/.cpp文件中如下定义
QStandardItem *m_currentItem; //当前点击item的指针
  1. 点击槽函数如下
void CMainWindow::on_tableView_clicked(const QModelIndex &index)
{
    //! 使用mapFromSource能获取到当前在过滤器上点击的index位于数据源模型上的index对象
    //! 在过滤器上点击的index位置和数据源模型上的index位置有可能会有偏差
    QModelIndex *dataModelxIndex = m_pFilterModel->mapToSource(index);
    //通过获取到的数据源上的index对象,获取行列值从而拿到item指针
    m_currentItem = m_pModel->item(dataModelxIndex->row(), dataModelxIndex->column());
}

总结

过滤器是个很好用的工具,但是在我查找相应资料时,听说对源数据模型做增加/删除操作会出现问题,这方便大家须得注意咯,总之,不做违规操作,一般不会出现问题!
那么今天就到这里吧,大家晚安啊!

相关文章

Qt代理的实现(按钮篇,含源码+注释)
Qt代理的实现(常规控件篇,含源码+注释)
Qt之QTableView的简单使用(含源码+注释)
Qt之QTableView设置多列表头复选框(自定义QHeaderView)、单元格复选框(含源码+注释)
Qt之QTreeView的简单使用(含源码+注释)
Qt之QListView的简单使用(含源码+注释)

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

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

  • 8
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lw向北.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值