Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved QTreeview filtering search

    General and Desktop
    qtreeview search filter
    5
    5
    10932
    Loading More Posts
    • 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.
    • JokerMartini
      JokerMartini last edited by

      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.

      the_ 1 Reply Last reply Reply Quote 0
      • the_
        the_ @JokerMartini last edited by

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

        -- No support in PM --

        1 Reply Last reply Reply Quote 1
        • VRonin
          VRonin last edited by VRonin

          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 Reply Quote 2
          • M
            mmoerdijk last edited by

            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

            raven-worx 1 Reply Last reply Reply Quote 0
            • raven-worx
              raven-worx Moderators @mmoerdijk last edited by

              @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 Reply Quote 2
              • First post
                Last post