[Qt-interest] Filtering only certain child rows of a tree model but include their parents when displaying (QSortFilterProxyModel)

Benjamin Meyer ben at meyerhome.net
Fri May 8 02:06:22 CEST 2009


I did what you are looking in Arora to filter the history, checkout  
the source for TreeProxyModel in Arora.

http://github.com/Arora/arora/blob/423ad2693dcee83f18e11ead6f76c81840f3fc7e/src/history/history.cpp

-Benjamin Meyer

On May 7, 2009, at 3:34 AM, Girish Ramakrishnan wrote:

> Andreas Ntaflos wrote:
>> 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?
>>
>
> I don't think it is possible to achieve what you want using
> QSortFilterProxyModel. It just doesn't support introspecting whether  
> the
> item has any matching children when filtering the parent.
>
> You will have to write your own QAbstractProxyModel or
> QAbstractItemModel to achieve what you want.
>
> Girish
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest




More information about the Qt-interest-old mailing list