QTreeView使用总结11,数据过滤,使用代理model,简单过滤

1,简介

有时候需要对tree内的数据按一些条件进行过滤显示,比如按搜索条件过滤,这时候就用到了代理model。
通常使用Qt提供的 QSortFilterProxyModel 类,该类实现了常见的按行列过滤的方法。
也可以自己从基类继承,重写 filterAcceptsRow 和 filterAcceptsColumn 来实现过滤:

virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const;

重写 lessThan 方法可实现排序:

virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;

本文先介绍直接使用QSortFilterProxyModel 类接口完成常见过滤功能的方法,后面介绍继承该类自定义过滤规则的方法。

2,参考资料

官方示例:在QtCreator的欢迎里搜“QSortFilterProxyModel”,出现2个示例。
Basic Sort/Filter Model Example 基础排序/过滤模型示例
Custom Sort/Filter Model Example 自定义排序/过滤模型示例

3,效果

这里写图片描述

4,实现

相比之前正常构造QTreeView的model的过程,这里需要新建一个QSortFilterProxyModel对象,并且设其源model为我们之前原始的model。然后把tree的model设为该QSortFilterProxyModel。
这样tree在显示时先访问该QSortFilterProxyModel,通过其提供的过滤规则最后从真实的model里面取数据进行显示,实现数据过滤。

主要代码如下:

void MainWindow::InitTree()
{
    //1,QTreeView常用设置项
    QTreeView* t = ui->treeView;
//    t->setEditTriggers(QTreeView::NoEditTriggers);			//单元格不能编辑
    t->setSelectionBehavior(QTreeView::SelectRows);			//一次选中整行
    t->setSelectionMode(QTreeView::SingleSelection);        //单选,配合上面的整行就是一次选单行
//    t->setAlternatingRowColors(true);                       //每间隔一行颜色不一样,当有qss时该属性无效
    t->setFocusPolicy(Qt::NoFocus);                         //去掉鼠标移到单元格上时的虚线框

    //2,列头相关设置
    t->header()->setHighlightSections(true);                //列头点击时字体变粗,去掉该效果
    t->header()->setDefaultAlignment(Qt::AlignCenter);      //列头文字默认居中对齐
    t->header()->setDefaultSectionSize(100);                //默认列宽100
    t->header()->setStretchLastSection(true);               //最后一列自适应宽度
    t->header()->setSortIndicator(0,Qt::AscendingOrder);    //按第1列升序排序

    //3,构造Model
    //设置列头
    QStringList headers;
    headers << QStringLiteral("年级/班级")
            << QStringLiteral("姓名")
            << QStringLiteral("分数")
            << QStringLiteral("评价");
    mModel = new QStandardItemModel(ui->treeView);
    mModel->setHorizontalHeaderLabels(headers);
    //设置数据
    QStringList names;
    names<<"aaa"<<"bbb"<<"ccc"<<"ddd"<<"eee"<<"abc"<<"abcdef";
    for(int i=0; i<names.size(); i++)
    {
        //二级节点:班级、姓名、分数
        QList<QStandardItem*> items;
        QStandardItem* itemClass = new QStandardItem(QStringLiteral("%1班").arg(i+1));
        QStandardItem* itemName = new QStandardItem(names.at(i));
        QStandardItem* itemScore = new QStandardItem("100");
        QStandardItem* itemAssess = new QStandardItem("优");
        items << itemClass << itemName << itemScore << itemAssess;
        mModel->appendRow(items);    //二级节点挂在一级的第1列节点上
    }
    //4,构造代理model,设置过滤列为第2列
    mProxyModel = new QSortFilterProxyModel;
    mProxyModel->setSourceModel(mModel);
    mProxyModel->setFilterKeyColumn(1);
    t->setModel(mProxyModel);
}

三个按钮设置三种不同的过滤形式:
根据正则表达式、通配符、普通文本

void MainWindow::on_btn1_clicked()
{
    //正则表达式
    //包含a、b、c中任意一个字符就满足
    QRegExp regExp("[abc]", Qt::CaseInsensitive, QRegExp::RegExp);
    mProxyModel->setFilterRegExp(regExp);
}

void MainWindow::on_btn2_clicked()
{
    //通配符
    //有bc的满足
    QRegExp regExp("bc*", Qt::CaseInsensitive, QRegExp::Wildcard);
    mProxyModel->setFilterRegExp(regExp);
}

void MainWindow::on_btn3_clicked()
{
    //文本
    //包含文本e的满足
    QRegExp regExp("e", Qt::CaseInsensitive, QRegExp::FixedString);
    mProxyModel->setFilterRegExp(regExp);
}

5,源码

链接:https://pan.baidu.com/s/1FgOHolNkzrKi1eRzvlpntw
提取码:qqpu

网盘若失效,可在群文件下载:
群号码:1149411109 (若满加2群:917341904)
群名称:Qt实战派学习群

  • 2
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逆枫゛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值