[Qt-interest] Filtering only certain child rows of a tree model but include their parents when displaying (QSortFilterProxyModel)
Andreas Ntaflos
daff at pseudoterminal.org
Thu May 7 05:01:39 CEST 2009
Hi list,
I apologise for this lengthy post but I tried to be as clear as possible
with my problem description so that a kind, knowledgeable soul will be
willing to help me :)
I am trying to apply a filter to a custom tree model (based closely on
[1] and [2]) with two columns. The second column is the filter key
column. I only want to filter certain child items (that are not parents
themselves, i.e. leaves), but still display their parents.
The first column holds the collapsible items that make up the tree and
the second column holds the data that I'd like to filter
(setFilterKeyColumn), but, as mentioned, only for those rows of the
source model that are not parents. See the following figure (best
viewed with a fixed-width font):
Figure 1: Tree model unfiltered
column 0 column 1
-----------------------------
ParentItem1 <empty>
- SubItem11 <empty>
- ChildItem111 data111
- ChildItem112 data112
- ChildItem113 data113
- SubItem12 <empty>
- ChildItem121 data121
- ChildItem122 data122
- SubItem13 <empty>
- ChildItem131 data131
- ChildItem132 data132
ParentItem2 <empty>
- SubItem21 <empty>
- ChildItem211 data211
- ChildItem212 data212
- SubItem22 <empty>
- ChildItem221 data221
- ChildItem222 data222
You see the model only returns a valid QVariant when a ChildItem is
encountered. For both a ParentItem or a SubItem an empty QVariant is
returned (return QVariant();).
Now I'd like to apply a filter based on a regular expression on column
1. Currently I use a standard QSortFilterProxyModel for this. The data
in column 1 is formatted reliably so a regexp can be applied easily.
Let's say the Regexp for column 1 is set to "data111|data112" (via
setFilterRegExp). What I'd like the proxy model to return is
illustrated in the following figure:
Figure 2: Model as it should be filtered by regexp "data111|data112"
column 0 column 1
-----------------------------
ParentItem1 <empty>
- SubItem11 <empty>
- ChildItem111 data111
- ChildItem112 data112
But, as you can probably imagine, the filter/regexp doesn't match any of
the rows that are <empty> in column 1, thus filtering away all parent
items of the ChildItems I'd like to filter. The end result is a
completely empty proxy model/tree view.
I have solved this for now by replacing <empty> with some special string
("####" for example) and including that string in the filter
regexp: "data111|data112|####". It is, however, not a very elegant
solution because this way all ParentItems and SubItems remain visible
in the filtered model, just their non-matching children are not:
Figure 3: Model is it is filtered by "data111|data112|####"
column 0 column 1
-----------------------------
ParentItem1 ####
- SubItem11 ####
- ChildItem111 data111
- ChildItem112 data112
- SubItem12 ####
- SubItem13 ####
ParentItem2 ####
- SubItem21 ####
- SubItem22 ####
- SubItem23 ####
Clearly it is undesirable to display all those items that have no
ChildItems under them. It clutters up the view and makes navigating the
filtered result harder.
What do I have to do to make my filter model behave like illustrated in
figure 2, i.e. filter only those rows that contain a ChildItem but
still display their parents and grandparents? Is there even a way?
Any and all help is appreciated!
Thanks in advance,
Andreas
[1] http://doc.trolltech.com/4.5/itemviews-simpletreemodel.html
[2] C++ Gui Programming with Qt 4, ch. 10, pp. 238 (the "RegExpModel")
--
Andreas Ntaflos
Vienna, Austria
GPG Fingerprint: 6234 2E8E 5C81 C6CB E5EC 7E65 397C E2A8 090C A9B4
More information about the Qt-interest-old
mailing list