Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTreeview filtering search
Forum Update on Monday, May 27th 2025

QTreeview filtering search

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtreeviewsearchfilter
5 Posts 5 Posters 13.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JokerMartini
    wrote on 4 Apr 2016, 13:14 last edited by
    #1

    I'm a bit new to the C++ Qt combo. I have a more solid background in C# and WPF. I want to create a treeview with filtering. The filtering would remove top level items which don't contain children that match the filter string. Below demonstrates how the results would work when a filter is used.

    • Sports
      |____ Soccer
      |____ Basketball
      |____ Football
      |____ Tennis
    • Teams
      |____ Cowboys
      |____ Packers
      |____ Lions
      |____ Tennessee
    • Players
      |____ Ronald
      |____ Warner
      |____ Robinson

    If i then searched with a filter string of 'Ten' It would result in this...

    • Sports
      |____ Tennis
    • Teams
      |____ Tennessee

    My question may seem simple, but how can i go about doing this? Creating a simple sample like this using QtCreator. I've added my QTreeView but I'm not entirely clear on how to populate it with dummy data and then filter it.

    T 1 Reply Last reply 4 Apr 2016, 14:42
    0
    • J JokerMartini
      4 Apr 2016, 13:14

      I'm a bit new to the C++ Qt combo. I have a more solid background in C# and WPF. I want to create a treeview with filtering. The filtering would remove top level items which don't contain children that match the filter string. Below demonstrates how the results would work when a filter is used.

      • Sports
        |____ Soccer
        |____ Basketball
        |____ Football
        |____ Tennis
      • Teams
        |____ Cowboys
        |____ Packers
        |____ Lions
        |____ Tennessee
      • Players
        |____ Ronald
        |____ Warner
        |____ Robinson

      If i then searched with a filter string of 'Ten' It would result in this...

      • Sports
        |____ Tennis
      • Teams
        |____ Tennessee

      My question may seem simple, but how can i go about doing this? Creating a simple sample like this using QtCreator. I've added my QTreeView but I'm not entirely clear on how to populate it with dummy data and then filter it.

      T Offline
      T Offline
      the_
      wrote on 4 Apr 2016, 14:42 last edited by
      #2

      @JokerMartini
      Maybe you should have a look at the QSortFilterProxyModel Class.

      -- No support in PM --

      1 Reply Last reply
      1
      • V Offline
        V Offline
        VRonin
        wrote on 4 Apr 2016, 15:22 last edited by VRonin 4 Apr 2016, 15:24
        #3

        Just subclass QSortFilterProxyModel

        // MySorter.h
        #include <QSortFilterProxyModel>
        class MySorter: public QSortFilterProxyModel
        {
            Q_OBJECT
        public:
            MySorter(QObject *parent);
        protected:
            virtual bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
        };
        
        // MySorter.cpp
        #include "MySorter.h"
        MySorter::MySorter(QObject *parent) : QSortFilterProxyModel(parent){}
        bool MySorter::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
        {
             // check the current item
             bool result = QSortFilterProxyModel::filterAcceptsRow(source,source_parent);
            QModelIndex currntIndex = sourceModel()->index(source_row, 0, source_parent);
            if (sourceModel()->hasChildren(currntIndex)) {
        // if it has sub items
                for (int i = 0; i < sourceModel()->rowCount(currntIndex) && !result; ++i) {
        // keep the parent if a children is shown
                    result = result || filterAcceptsRow(i, currntIndex);
                }
            }
            return result;
        }
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        2
        • M Offline
          M Offline
          mmoerdijk
          wrote on 19 Mar 2018, 20:23 last edited by
          #4

          This example helped me a lot, I implemented it in python. Hereby the corresponding code:

          class FilterProxyModel(QtCore.QSortFilterProxyModel):
              def __index__(self):
                  super(FilterProxyModel, self).__index__(self)
          
              def filterAcceptsRow(self, p_int, QModelIndex):
                  res = super(FilterProxyModel, self).filterAcceptsRow(p_int, QModelIndex )
                  idx = self.sourceModel().index(p_int,0,QModelIndex)
                  
                  if self.sourceModel().hasChildren(idx):
                      num_items = self.sourceModel().rowCount(idx)
                      for i in xrange(num_items):
                          res = res or self.filterAcceptsRow(i, idx)
          
                  return res
          

          I hope it helps someone els

          R 1 Reply Last reply 19 Mar 2018, 20:25
          0
          • M mmoerdijk
            19 Mar 2018, 20:23

            This example helped me a lot, I implemented it in python. Hereby the corresponding code:

            class FilterProxyModel(QtCore.QSortFilterProxyModel):
                def __index__(self):
                    super(FilterProxyModel, self).__index__(self)
            
                def filterAcceptsRow(self, p_int, QModelIndex):
                    res = super(FilterProxyModel, self).filterAcceptsRow(p_int, QModelIndex )
                    idx = self.sourceModel().index(p_int,0,QModelIndex)
                    
                    if self.sourceModel().hasChildren(idx):
                        num_items = self.sourceModel().rowCount(idx)
                        for i in xrange(num_items):
                            res = res or self.filterAcceptsRow(i, idx)
            
                    return res
            

            I hope it helps someone els

            R Offline
            R Offline
            raven-worx
            Moderators
            wrote on 19 Mar 2018, 20:25 last edited by
            #5

            @mmoerdijk
            since Qt 5.10 there is a recursiveFilteringEnabled property on a QSortFilterProxyModel, which does exactly this.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            2

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved