Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to show a subpart of a treeModel in QTreeView



  • I have the following tree model structure:

    rootItem:
        item 1
            item 1.1
                item 1.1.1
                item 1.1.2
            item 1.2
            item 1.3
        item 2
            item 2.1
            item 2.2
        item 3
            item 3.1
            item 3.2
    
    

    I show the full tree model in one treeVew and in another treeView I would like to show just a subpart of the tree. If item 1.1 is selected the second treeView should show only the children of item 1.1. How can I achieve this?



  • @Infinity

    1. So in principle you should just respond to selection of a node in treeview1 by setting the root item of treeview2 to that node.

    2. Another possibility is to make treeview2 go via proxy model off the model for treeview1. But I'm thinking #1 will do you?



  • @JonB I would like to have the same model. Because if one item is deleted in the second treeView it should also be deleted in the first treeView. I tried it with a proxy model, but I got stuck there. Here is my proxy model:

    #include "treemodelownerproxyfilter.h"
    #include "treemodel.h"
    
    TreeModelOwnerProxyFilter::TreeModelOwnerProxyFilter(QModelIndex &currentIndex) :
        m_ownerNodeIndex(currentIndex)
    {
    
    }
    
    bool TreeModelOwnerProxyFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    {
        TreeModel *treeModel = qobject_cast<TreeModel *>(sourceModel());
    
        QModelIndex ownerIndex = treeModel->index(sourceRow, 0, sourceParent);
        TreeItem *ownerItem = treeModel->treeItem(ownerIndex);
    
        qDebug() << "\n";
        qDebug() << "owner node index:" << m_ownerNodeIndex;
        qDebug() << "source parent   :" << sourceParent;
        qDebug() << "source row      :" << sourceRow;
        qDebug() << "owner index     :" << ownerIndex;
        qDebug() << "owner parent    :" << treeModel->parent(ownerIndex);
        qDebug() << "tree model      :" << treeModel;
        qDebug() << "owner item      :" << ownerItem;
    
        if (m_ownerNodeIndex == treeModel->parent(ownerIndex)) return true;
        else return false;
    }
    

    Here is the output of qDebug():

    owner node index: QModelIndex(0,0,0x13d35c0,TreeModel(0x143c920))
    source parent   : QModelIndex(-1,-1,0x0,QObject(0x0))
    source row      : 0
    owner index     : QModelIndex(0,0,0x13cc540,TreeModel(0x143c920))
    owner parent    : QModelIndex(-1,-1,0x0,QObject(0x0))
    tree model      : TreeModel(0x143c920)
    owner item      : 0x13cc540
    
    owner node index: QModelIndex(0,0,0x13d35c0,TreeModel(0x143c920))
    source parent   : QModelIndex(-1,-1,0x0,QObject(0x0))
    source row      : 1
    owner index     : QModelIndex(1,0,0x1435080,TreeModel(0x143c920))
    owner parent    : QModelIndex(-1,-1,0x0,QObject(0x0))
    tree model      : TreeModel(0x143c920)
    owner item      : 0x1435080
    
    owner node index: QModelIndex(0,0,0x13d35c0,TreeModel(0x143c920))
    source parent   : QModelIndex(-1,-1,0x0,QObject(0x0))
    source row      : 2
    owner index     : QModelIndex(2,0,0x14316f0,TreeModel(0x143c920))
    owner parent    : QModelIndex(-1,-1,0x0,QObject(0x0))
    tree model      : TreeModel(0x143c920)
    owner item      : 0x14316f0
    

    It seems that it stops when one of the parent items doesn't match the criteria.



  • It seems that it stops when one of the parent items doesn't match the criteria.

    I'm sorry I don't have time to look right now, but: you don't show what your TreeModelOwnerProxyFilter is derived from. If, say, it's from QSortFilterProxyModel you need to use the (new at Qt 5.10) https://doc.qt.io/qt-5/qsortfilterproxymodel.html#recursiveFilteringEnabled-prop to allow the descent recursively to find descendants when a node itself does not match the filter. And if you're writing your own code something similar. Maybe that's where your code does not proceed?



  • @JonB Yes. my proxyModel is derived from QSortFilterProxyModel. I set now setRecursiveFilteringEnabled(true) and it already looks much better. Now it shows the whole branch in the second treeView. Like this:

    item 1
        item 1.1
            item 1.1.1
            item 1.1.2
    

    ... and not just the two items. It would like to show just item 1.1.1 and item 1.1.2 if item 1.1 is selected in the first treeView. If item 1.1 is selected it should show in the second treeView:

    item 1.1.1
    item 1.1.2
    

    Any idea how I have to change filterAcceptsRow?


  • Lifetime Qt Champion

    Hi,

    Isn't setRootIndex what you are looking for ?



  • @SGaist Yes. That is what I was looking for. Thank you very much.



  • @SGaist The tree model looks like this now:

    rootItem:
        item 1
            item 1.1
                item 1.1.1
                    item 1.1.1.1
                    item 1.1.1.2
                    item 1.1.1.3
                item 1.1.2
            item 1.2
            item 1.3
        item 2
            item 2.1
            item 2.2
        item 3
            item 3.1
            item 3.2
    

    Now my filterAcceptsRow works. It shows just item 1.1.1 and item 1.1.2. But now I would like to show also the children of these items. What is the easiest way to achieve this?


  • Lifetime Qt Champion

    You should show your method implementation.


Log in to reply