QSortfilterproxymodel - simulate "new" root index?



  • Hey

    Say I have tree like this >

    invisibleRoot
        child0
        child1
        child2
            child2ChildA
            child2ChildB
            child2ChildC
            child2ChildD << set this as new root?
                childDChild1
                childDChild2
                childDChild3
                childDChild4
    

    And here is the proposed filterAcceptsRow command... but its not getting me exactly what I want... I get to see the item + its children + all his parents(recursively), but I don't want to see that item parent stack... and overall I think it's bad due to the recursive looping per item... mmm what to do ? Ideally I want to control if I set the item as invisbleRoot item so header change to that item data() items, or if I just have it as 1st item at the top of the tree...

    bool filterRootReplacement::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const {
        if (!mFilterByNewRoot) {
            return true;
        } else {
            QModelIndex currentItem = sourceModel()->index(source_row, 0, source_parent);
            if (currentItem.data(treeEnumsTest::itemId).isValid()) {
                if (currentItem.data(treeEnumsTest::itemId).toString() == mRootId) {
                    return true;
                }
                //// Check parents if they are the key item; I don't think I need it in this filter function. Its from other filter model.
                QModelIndex i = currentItem;
                while (i.isValid()) {
                    i = i.parent();
                    if (i.data(treeEnumsTest::itemId).toString() == mRootId) {
                        return true;
                    }
                }
                //// Check if any of the children is the one with id. //// but I dont wan't to display this item... sigh.
                int childCount = sourceModel()->rowCount(currentItem);
                for (int x = 0; x < childCount; ++x) {
                    if (checkChildrenForParent(currentItem.child(x, 0))) {
                        return true;
                    }
                }
            } else {
                return true;
            }
        }
        return false;
    }
    
    bool filterRootReplacement::checkChildrenForParent(QModelIndex &&inx) const {
        if (inx.data(treeEnumsTest::itemId).toString() == mRootId) {
            return true;
        }
        int c = sourceModel()->rowCount(inx);
        for (int x = 0; x < c; ++x) {
            if (checkChildrenForParent(inx.child(x, 0))) {
                return true;
            };
        }
        return false;
    }
    

    desired look either:

    invisibleRoot
            child2ChildD << set this as new root?
                childDChild1
                childDChild2
                childDChild3
                childDChild4
    

    or

            child2ChildD << set this as new root? - becomes new header
                childDChild1
                childDChild2
                childDChild3
                childDChild4
    

  • Qt Champions 2018



  • @Christian-Ehrlicher So I spend like 2h on R&Ding this amazing function and there is already something like that in qtreeView... great............... :- )))))))))))))))))))))))

    This solves this scenario mostly - except that header still remains from old model, which is actually fine...

    invisibleRoot
          child2ChildD << QTreeView::setRootIndex();
                childDChild1
                childDChild2
                childDChild3
                childDChild4
    

    How about this scenario?

            child2ChildD << selected item as root
                childDChild1
                childDChild2
                childDChild3
                childDChild4
            childX2ChildD  << another selected item as root. In case user wishes to see multiple items isolated ?
                childDChild1
                childDChild2
                childDChild3
                childDChild4
    

    Actually the more I think of it the more I need a method where I can select items, and then only show these items + their children.... hmmm - like isolate selected?



  • So this needs a bump now, I tried using setRootIndex but that did not work... https://forum.qt.io/topic/102454/qtreeview-setrootindex-changing-header-incorrect-columncount/6

    So I'm back to proxyModels... my main issue now is, how can I set a new rootIndex/item to that sortFilterProxy kick in from right infex and not from old index?


    As far as I can tell the filtering starts when tree request item, which usually is the root item, so header item. Since thats not the item I want to show I return false & since I return false there are no more items to query - thus no children thus the item that I actually want to show as new root never gets called/checked... if I use filterAcceptsRow() function... so where/who do I change to set different rootItem via proxy model?


Log in to reply