Reputation: 191
My Qt-Application was built based on the EditableTreeModel
example from Qt. In the TreeModel
class there is a function called getItem()
which takes the QModelIndex
as a parameter and returns a TreeItem
.
For my Application I need the reverse function: getting the QModelIndex
from an TreeItem
. This should be independent from the View. This means that I can't use the function QTreeView::currentIndex()
.
Is there any good solution for my problem?
Upvotes: 7
Views: 11756
Reputation: 1072
You can build a map from TreeItem
to QModelIndex
as following :
void buildMap(const QModelIndex &index, const QAbstractItemModel *model, QMap<TreeItem *, QModelIndex> &itemMap)
{
if( !index.isValid() )
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
itemMap.insert( item, index );
int rows = model->rowCount(index);
int cols = model->columnCount(index);
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j){
QModelIndex idChild = model->index(i, j, index);
buildMap( idChild , model, itemMap );
}
}
The function buildMap should be used as :
QMap<TreeItem *, QModelIndex> itemMap;
TreeModel *model = static_cast<TreeModel *>(view->model());
for (int row = 0; row < model->rowCount(); ++row){
buildMap( model->index(row,0), model, itemMap );
}
qDebug() << "Item map count : " << itemMap.count();
foreach( TreeItem * item, itemMap.keys( )){
qDebug() << "item " << item << " -> " << itemMap[ item ];
}
Output:
Item map count : 35
item 0xbe1fe8 -> QModelIndex(1,1,0xbe1fe8,TreeModel(0x4421390))
item 0xbe2020 -> QModelIndex(2,1,0xbe2020,TreeModel(0x4421390))
item 0xbe22f8 -> QModelIndex(3,1,0xbe22f8,TreeModel(0x4421390))
item 0xbe2330 -> QModelIndex(2,0,0xbe2330,TreeModel(0x4421390))
...
Upvotes: 0
Reputation: 28659
You need to call QAbstractItemModel::createIndex
passing in the correct row
, column
and the item iteself.
The following should work:
QModelIndex TreeModel::indexForTreeItem(TreeItem* item)
{
return createIndex(item->childNumber(), 0, item);
}
An explanation of how I came to this:
createIndex
also takes a void*
data pointer, which in the EditableTreeModel
TreeModel
example code, is a pointer to the TreeItem
. You can see this is the case in the TreeModel::index
member function:
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() != 0)
return QModelIndex();
TreeItem *parentItem = getItem(parent);
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem); // <-- here childItem is the TreeItem*
else
return QModelIndex();
}
Note that QAbstractItemModel::createIndex
is a protected function, so you have to add a new member function to your TreeModel
which creates the QModelIndex
for you.
In order to calculate the row for a given TreeItem
there is a member function childNumber
which returns its index in its parent's list of children (ie: its row)
Unfortunately it is not possible to calculate the column for a given TreeItem
, as a TreeItem
contains all the data for its columns, so encompasses all columns. As such, a reasonable default would be to use 0
(the left-most column)
Upvotes: 5