PDA

View Full Version : Finding a item in second column of treeView



cszawisza
17th September 2013, 19:25
Hi.
The topic was discussed couple of time on this forum, but not in the way that satisfies me.
My tree looks like


name DESC
|-> ENTRY ID_100
|-> ENTRY ID_101
|-> ENTRY_2 ID_102
|-> ENTRY_2 ID_103

It has 2 columns, first with name and second with ID (unique) what I want to do is to find index of ENTRY, when having only ID, and I really don't know how to do that.
I'm now trying to use the match() function but with no success. When I look for text in first column everything works great.
Code

QModelIndexList Items = model->match(
model->index(0, 0),
Qt::DisplayRole,
QVariant::fromValue(QString("ENTRY_2")),
-1,
Qt::MatchRecursive);

returns me indexes of all entries with same text, but changing code to

QModelIndexList Items = model->match(
model->index(0, 1),
Qt::DisplayRole,
QVariant::fromValue(102),
-1,
Qt::MatchRecursive);

results in empty list of indexes.
Is there a simple way to find index of "ENTRY" by finding the ID?

ChrisW67
17th September 2013, 20:51
In your example the DisplayRole of the second column would be QVariant("ID_102") not QVariant(102). If that was not done for illustrative purposes then this may be why your result set is empty.

cszawisza
17th September 2013, 21:08
ID in my code is the same in tree and in code.
The "ID_" tag in my "visual" illustration is only for shoving that this is ID column not a text from NAME column :) in real life is equal to "102"

wysota
18th September 2013, 07:50
Show us the implementation for data(), please.

cszawisza
18th September 2013, 19:17
I've manage to solve my problem by changing sqlQuery, to get not only ID but also name. Then I look for entries that match my groupName, and then for every match I check second column for fit with the ID.


currentGroupID = query.value("groupID").toInt();
QAbstractItemModel *model = ui->groupTree->model();
QModelIndexList Items = model->match(
model->index(0,0),
Qt::DisplayRole,
QVariant::fromValue(QString(query.value("groupName").toString())),
-1,
Qt::MatchRecursive);
if (Items.size() == 1){
// Only 1 group with this name ID must match
doSomethingWithGroup(Items.first());
}
else{
for(int i=0;i<Items.size();i++){
QModelIndex parent = Items.at(i).parent();
int tmpGroupID = Items.at(i).model()->index(0,1,parent).data().toInt();
if (tmpGroupID == currentGroupID){
doSomethingWithGroup(Items.at(i));
break;
}
}
}

It work for me but, the main topic still remains unsolved.
I use QStandardItemModel so data() is a buildin function.

ChrisW67
20th September 2013, 00:19
Ok. The default implementation of match() only searches in a column (as documented). The only column in which a recursive search makes sense is column 0 (the only one with a hierarchy) and that column does not contain the values you are seeking. You need to provide a reimplementation of match() if you wish to recurse down column 0 but search a different (or all) columns in each row.

You could also/instead store the ID on the Qt::UserRole of the item in column 0 to allow match() to search that way.


#include <QApplication>
#include <QStandardItemModel>
#include <QTreeView>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QStandardItemModel model;

for (int i = 0; i < 4; ++i) {
QStandardItem *parentItem = model.invisibleRootItem();
for (int j = 0; j < 3; ++j) {
QStandardItem *item0 = new QStandardItem(QString("item %0").arg(j));
item0->setData(100 + j, Qt::UserRole);
QStandardItem *item1 = new QStandardItem(QString::number(100 + j));
parentItem->appendRow(QList<QStandardItem*>() << item0 << item1);
parentItem = item0;
}
}

QModelIndexList matches = model.match(
model.index(0,0),
Qt::UserRole,
QVariant(102),
-1,
Qt::MatchRecursive);

QTreeView view;
view.setModel(&model);
view.show();
view.expandAll();
foreach (const QModelIndex &match, matches)
view.selectionModel()->select(match, QItemSelectionModel::Select);

return a.exec();
}