PDA

View Full Version : Highlight Tree Item Viw



sajis997
15th June 2011, 08:45
Hello forum,

I am trying to highlight a particular tree-item based on the string entered by the user in the line edit and i am doing the following:


1. I subclass the QSortFilterProxyModel and over-ride the data() function as follows:

1.1. map the model index to the source.

1.2. Check if the mapped model index is valid or not.

1.3. And change the color of the background using the background role.

2. In the widget i have the line edit and the tree view which will be interacting with each other based on the user input.

3. In the widget's constructor i instantiate the object of the subclass that i have creaed in step 1.

4. Set its source model.

5. Set view to both the model and proxy model.

6. Made a signal & slot connection - whenever the text inside the textedit is changed, the custom slot is called to do the highlighting s follows:


6.1. Create a regular expression object , which takes the following parameter:

6.1.1. The text from the line edit - 1st parameter.
6.1.2. Flag - Qt::CaseInsensitive.
6.1.3. Flag - Qt::FixedString.


6.2. Declare two model indexes and initializing as follows(THIS IS WHERE I AM MAKING THE MISTAKE I GUESS):



const QModelIndex topLeft = m_highlightModel->index(0,0,QModelIndex());
const QModelIndex bottomRight = m_highlightModel->index(0,m_highlightModel->columnCount()-1,topLeft);









emit proxyModelHighlightChanged(topLeft,bottomRight);



//emit m_highlightModel->dataChanged(topLeft,bottomRight);


connect(this,SIGNAL(proxyModelHighlightChanged(QMo delIndex,QModelIndex)),m_highlightModel,SIGNAL(dat aChanged(QModelIndex,QModelIndex)));




Now i am not getting the effect i am looking for. I am looking for the following:



1. Whenever the user enters any text in the line edit, the text will be matched against all the tree item and highlighted.


2. Some of the item may be hidden as the parent item is not expanded. In that case the parent will be expanded and the child will be
highlighted.


3. If the entered string does not match , nothing will happen.



But i am getting the following:


1. All the items are highlighted, when the application is loaded.

2. The item inside the tree is filtered when the entered string matches any item, thus reducing the number of items in the tree . I do not want to alter anything inside the

tree view. I just want to highlight the tree item by changing the background color.


3. I can match only the parent item, but cannot go down to the child and sub-childs item and high-light it.


I hope that i am elaborated enough. If it is not clear enough for any one of you, please do not hesitate to comment. It has been
quite a while i am stuck with this issue. Any tips will be helping a lot.



NOTE: Couple of days ago my email account has been cracked and it might had spammed the forum. If there were anything totally
non-related to Qt, it was not me. The account setting is restored now. If those materials disturbed anyone i deeply apologise
for it.


Thanks
Sajjad

Santosh Reddy
16th June 2011, 03:58
5. Set view to both the model and proxy model.
You should be setting model to both the view and proxy model (may be just a typo)

const QModelIndex topLeft = m_highlightModel->index(0,0,QModelIndex());
const QModelIndex bottomRight = m_highlightModel->index(0,m_highlightModel->columnCount()-1,topLeft);
This will not work, as you are just cheking the first row, rest of the rows are ignored


You should be running the search on all the items recessively something like this


// Check for the string, including all children
void filterCheck(const QModelIndex & parent) //Pass root index here, it should take care of rest
{
if(parent.isValid())
{
if(!parent.data().toString().isNull())
{
bool value = false;
if(LineEdit filter is matching) // Check filter
value = true;
emit highlightItem(parent, value);
}

int rowCount = parent.model()->rowCount(parent);
int colCount = parent.model()->columnCount(parent);

for(int i = 0; i < rowCount; i++)
for(int j = 0; j < colCount; j++)
filterCheck(parent.model()->index(i, j, parent)); //recursive call
}
}

sajis997
19th July 2011, 00:21
Hello Santosh,

I have tried to follow the suggestion as follows:



QVariant H3DHighlighterProxyModel::filterCheck(const QModelIndex &parent) const
{
if(!filterRegExp().isEmpty())
{
if(sourceModel()->data(parent).toString().contains(filterRegExp()))
{
return Qt::yellow;
}
else
{
int rowCount = parent.model()->rowCount(parent);
int columnCount = parent.model()->columnCount(parent);

for(int i = 0; i < rowCount; i++)
for(int j = 0; j < columnCount; j++)
filterCheck(parent.model()->index(i,j,parent));
}
}
else
{
//return the default background color
//whatever may it be
return QVariant();
}
}


QVariant H3DHighlighterProxyModel::data(const QModelIndex &index, int role) const
{
//get the handle to the underlyiing data - map the model index to the source model index
QModelIndex sourceIndex = mapToSource(index);

//make sure that the model index is valid
if(!sourceIndex.isValid())
{
return QVariant();
}

if(role == Qt::BackgroundRole)
{
return filterCheck(sourceIndex);
}
else
{
return sourceIndex.data(role);
}
}




But i am getting the same effect as before. Do i have to check for like if the the tree-view is expanded or not, because the child item is not highlighted.

And again,i have sub-classed the QSortFilterProxyModel and i have over-ridden the data() function as you can see in the above code snippet. I am getting the highlighting effect as before on the parent item and not to the child items . The items that are not matched are removed from the tree view. I do not want the tree view to change at all. I just want the matched item to be highlighted and the non-matched item to remain same as it was in the tree-view.

Any more hint on the issue?


Regards
Sajjad

Santosh Reddy
19th July 2011, 04:55
Ok, try this, sub-class QSortFilterProxyModel, and re-implement only data(), like this


QVariant H3DHighlighterProxyModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::BackgroundRole)
{
QString text = QSortFilterProxyModel::data(index).toString();

if(text.contains(hightLight) and !hightLight.isEmpty()) // QString hightLight; //match string, replace this with QRegExp if required.
return QColor(Qt::lightGray); //hightlight color
}
return QSortFilterProxyModel::data(index, role);
}

this is simple, and will work

sajis997
19th July 2011, 09:40
Hello Santosh,

I am getting the old effect as before. Let me elaborate again , i must be missing something here.

In one of the previous posts you have mentioned to Set view to both the model and proxy model. Does it mean something as follows:

treeView->setModel(sourceModel);

treeView->setModel(proxyModel);


I do not understand the point of doing above. Instead should not it be something as follows:





highlightModel = new highlightModel(this); // subclass of the QSortFilterProxyModel
highlightModel->setSourceModel(sourceModel);

treeView->setModel(highlightModel);





Regards
Sajjad