QTreeview filtering search
-
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.
- Sports
-
@JokerMartini
Maybe you should have a look at the QSortFilterProxyModel Class. -
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; }
-
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
-
@mmoerdijk
since Qt 5.10 there is a recursiveFilteringEnabled property on a QSortFilterProxyModel, which does exactly this.