Monday, December 01, 2008

Filtering QTreeView

While working on my newest project, I had a miserable time figuring out how to filter sub-items in QTreeView and its associated models (like in kopete/pidgin). The first thing to do is to use QSortFilterProxy as a middleman. The problem is that QSortFilterProxy will only search top level tree nodes.
The way to implement custom filters is to subclass QSortFilterProxy and reimplement filterAcceptsRow(). But I couldn't figure out any way to quickly access sub elements using QModelIndex, nor could I find anything on the 'net. So after quite a lot of fiddling around, I managed to get this, which works. So to save someone else some time, here is the code



bool MemberFilter::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
if( sourceParent.isValid() && sourceModel()->data(sourceParent).toString().contains(filterRegExp()) ) return true;

QString data = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).toString();

bool ret = data.contains(filterRegExp());

QModelIndex subIndex = sourceModel()->index(sourceRow, 0, sourceParent);
if( subIndex.isValid() )
{
for(int i = 0; i < sourceModel()->rowCount(subIndex); ++i)
{
ret = ret || filterAcceptsRow(i, subIndex);
}
}
return ret;
}



On a side note, this has been a post after a long long time. This is because I've decided only to post important things or code related stuff. Right now I finished one semester of college, and will be home for a month.

2 comments:

  1. Thank you from the bottom of my heart. I've also had a miserable time trying to get this to work for more than one week.

    ReplyDelete