Obviously, I can't test your code, but I think this will be a problem:
bool H3DHighlighterProxyModel
::filterAcceptsRow(int source_row,
const QModelIndex &source_parent
) const {
QColor highLighter
= Qt
::cyan;
if(sourceModel()->data(source_parent).toString().contains(filterRegExp()))
{
sourceModel
()->setData
(source_parent,
QVariant(highLighter
),Qt
::BackgroundColorRole);
return true;
}
return false;
}
bool H3DHighlighterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QColor highLighter = Qt::cyan;
if(sourceModel()->data(source_parent).toString().contains(filterRegExp()))
{
sourceModel()->setData(source_parent,QVariant(highLighter),Qt::BackgroundColorRole);
return true;
}
return false;
}
To copy to clipboard, switch view to plain text mode
If I understand the docs correctly, returning false for any row will stop the recursion into the children of that row. So you have to accept all rows, but only set the highlight color for the rows that match. Returning false says "this row doesn't match, so remove it (and all its children) from the proxy model". That isn't what you want, if I understand correctly. You want your proxy model to contain everything that is in your tree, just some of them should be highlighted.
I am not sure step 4 is necessary; setting the background color in the filter will do it all, because the default behavior of the QSortFilterProxyModel will retrieve the background color. In any case, you have not implemented it correctly. I do not know what "item" is supposed to be. If it is some parent index for the model index that is passed into the data() method, then you need to be returning this:
return item->data(index.column(), role );
return item->data(index.column(), role );
To copy to clipboard, switch view to plain text mode
otherwise you get the data for the default role (Qt:
isplayRole), not the QBrush for the background or foreground roles.
The data() method is basically a lookup into a hash map by role. For every role, there is a default value; by overriding the data() method for specific roles, you are telling the model-view mechanism to use the data you specify for that role, not the default.
So, if what you are trying to do is to highlight the parent and all of the children for a node that matches the search string, I think you need to do something like this in your filterAcceptsRow() method:
bool H3DHighlighterProxyModel
::filterAcceptsRow(int source_row,
const QModelIndex &source_parent
) const {
QColor highLighter
= Qt
::cyan;
QColor noHighlighter
= Qt
::white;
// If the source data (retrieved using the default Qt::DisplayRole) matches the filter,
// then set its background to the highlight color
if( sourceModel()->data(source_parent).toString().contains(filterRegExp()) )
{
sourceModel
()->setData
(source_parent,
QVariant( highLighter
),Qt
::BackgroundColorRole);
}
else
{
// If you want all children of a matching parent to be highlighted, then do this:
// Set the background color to the same color as its parent
if ( parent.isValid() )
{
QVariant bkgnd
= sourceModel
()->data
( parent, Qt
::BackgroundRole );
sourceModel()->setData(source_parent, bkgnd,Qt::BackgroundColorRole);
}
else
sourceModel
()->setData
(source_parent,
QVariant( noHighLighter
),Qt
::BackgroundColorRole);
}
return true;
}
bool H3DHighlighterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QColor highLighter = Qt::cyan;
QColor noHighlighter = Qt::white;
// If the source data (retrieved using the default Qt::DisplayRole) matches the filter,
// then set its background to the highlight color
if( sourceModel()->data(source_parent).toString().contains(filterRegExp()) )
{
sourceModel()->setData(source_parent,QVariant( highLighter ),Qt::BackgroundColorRole);
}
else
{
// If you want all children of a matching parent to be highlighted, then do this:
// Set the background color to the same color as its parent
const QModelIndex & parent = source_parent.parent();
if ( parent.isValid() )
{
QVariant bkgnd = sourceModel()->data( parent, Qt::BackgroundRole );
sourceModel()->setData(source_parent, bkgnd,Qt::BackgroundColorRole);
}
else
sourceModel()->setData(source_parent,QVariant( noHighLighter ),Qt::BackgroundColorRole);
}
return true;
}
To copy to clipboard, switch view to plain text mode
The last step (if parent is not valid) will have the result of setting all non-matching items to the white background color - the first time though the method, the model index will be the root item (0,0). If it doesn't match, then it will be set to the white background color since it has no parent . As the recursion proceeds, any of its children that don't match will also be set to white background, and so on.
I hope I have understood what you are trying to do 
And by the way, the docs say to use Qt::BackgroundRole instead of Qt::BackgroundColorRole. Both will work for now, but BackgroundColorRole has been declared as obsolete and might be removed in a later version of Qt.
Bookmarks