Avoid redundant calls to QSortFilterProxyModel::filterAcceptsRow() if the filter has become strictly narrower

后端 未结 2 906
孤独总比滥情好
孤独总比滥情好 2021-02-14 05:25

Is there any way invalidate the filter in a QSortFilterProxyModel, but to indicate that the filter has been narrowed down so filterAcceptsRow() should be called onl

2条回答
  •  我在风中等你
    2021-02-14 05:38

    Because the filters can also be generic (for custom filter sorting you are encouraged to override filterAcceptsRow()) the ProxyModel cannot know whether it will become narrower or not.

    if you would need to provide it to the proxy as a parameter it would break encapsulation because the filter-logic should only be contained inside the filter model.

    You cannot override invalidateFilter though because it is not declared virtual. What you can do is having a structure in your derived proxy where you store the values you lastly filtered in there and only check them in , when the filter just got narrower. Both of this you can do in filterAcceptsRow().

    invalidateFilter() still will call rowCount() though. So this function needs to have a low call time in your model for this to be effective.

    Here is some pseudocode how filterAcceptsRow() could look like:

    index // some index to refer to the element;
    
    if(!selectionNarrowed()) //need search all elements
    {
        m_filteredElements.clear(); //remove all previously filtered
        if(filterApplies(getFromSource(index))) //get element from sourceModel
        {
            m_filteredElements.add(index); //if applies add to "cache"
            return true;
        }
        return false;
    }
    
    //selection has only narrowed down    
    if(!filterApplies(m_filteredElements(index)) //is in "cache"?
    {
        m_filteredElements.remove(index); //if not anymore: remove from cache
        return false;
    }
    return true;
    

    There are some things to be aware of though. Be careful if you want to store the QModelIndex..You can have a look at QPersistentModelIndex.

    You also need to be aware about changes in the underlying model and connect the appropriate slots and invalidate your "cache" in those cases.

    While an alternative could be "filter stacking". I see this may get confusing when you really need to invalidate all filters.

提交回复
热议问题