转载:Qt之QSortFilterProxyModel过滤所有子项

通常若是须要对一个视图进行关键字过滤,咱们会使用QT的类QSortFilterProxyModel,将视图(view)的模型设置为这个代理类,将代理类的源模型定义为原始模型,而后定义代理模型的filterKeyColumn, filterRole, filterFixString或filterRegExp等属性后就能够实现过滤功能。如:函数

MyTreeModel model;  
QSortFilterProxyModel sfmodel;  
MyView view;  
  
view.setModel(&sfmodel);  
sfmodel.setSourceModel(&model);  
sfmodel.setFilterKeyColumn(0);  // optional  
sfmodel.setFilterRole(Qt::DisplayRole); // default, optional  
sfmodel.setFilterFixedString("keyword");  
sfmodel.setFilterRegExp("[hH]ello");

    可是对于TreeView和TreeModel,这样的作法有些缺陷,若是在子节点上的数据根据过滤规则能够显示,但它的parent节点根据过滤规则是不显示的。这样一来会由于父节点被过滤掉,而致使符合条件的子节点也一块儿被过滤掉了。若是须要对这个缺陷进行改进,能够这样来作:从QSortFilterProxyModel继承一个本身的代理类,从新实现它的filterAcceptsRow函数,当节点不是一个叶子节点(在末端,没有子节点)时不该用过滤规则,只对叶子节点应用过滤规则,这样就能够达到上述要求。代码以下:
spa

bool MyFilterProxyModel::filterAcceptsRow ( int source_row,  
                            const QModelIndex & source_parent ) const  
{  
    QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);  
    if (sourceModel()->rowCount(source_index)>0)  
        return true;  
    else  
        return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);  
}

    上面的代码会带来一个新的缺陷,就是对于非叶子节点不该用过滤规则,对于那些没有子节点符合过滤规则,且自身节点也不符合过滤规则的节点,也会一直在视图中显示。若是须要弥补这个问题,能够继续作如下的改进:在应用过滤规则时,若是自身不符合过滤规则,再去检查全部的子节点(递归调用至全部的后代节点),若全部的子节点都不符合过滤规则,那么这个子节点就不显示,只要有一个后代节点符合规则,就须要显示这个节点。代码以下:代理

bool MyFilterProxyModel::filterAcceptsRow ( int source_row,  
                            const QModelIndex & source_parent ) const  
{  
    bool filter = QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);  
  
    if (filter)  
    {  
        return true;  
    }  
    else  
    {  
        // check all decendant's  
        QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);  
        for (int k=0; k<sourceModel()->rowCount(source_index); k++)  
        {  
            if (filterAcceptsRow(k, source_index))  
            {  
                return true;  
            }  
        }  
    }  
  
    return false;  
}

按照这样的作法,就能够达到一个比较理想的过滤效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值