PDA

View Full Version : QAbstractItemModel to wrap multiple QStandardItemModels throws ASSERT in QTreeView



gvd
20th October 2009, 01:57
Hi,

I'm trying to subclass QAbstractItemModel so I can add multiple QStandardItemModels and show them in a single QTreeView. Something like:



CombinedTreeModel * combined = new CombinedTreeModel (0);
combined ->addStandardItemModel(model1);
combined ->addStandardItemModel(model2);
combined ->addStandardItemModel(model3);

model1, 2, and 3 are QStandardItemModels and the addStandardItemModel(...) adds the top node of each model to an internal root node in CombinedTreeModel
I used the "simpletreemodel" as an example but instead of using a QStandardItem as the internal rootItem I created a private Root class which inherits from QStandardItem:



class Root : public QStandardItem
{
public:
QList<QStandardItem*> child;

};


I do this because I add the top nodes of the sub-models using model1->item(0) and NOT model1->takeItem(0). I want the original models to keep ownership. I will paste some of the methods I implemented in order to do this below. Unfortunately my code doesn't seem to work when plugging it into a "QTreeView-setModel(combined)". The first node expands just fine (it goes from child0->child1->child2->child3) but the other 2 top-nodes throw an ASSERT when i try to expand child2:

File: global\qglobal.cpp
Line: 2090

ASSERT: "i > -1" in file itemviews\qtreeview.cpp, line 3038

The ASSERT appears to occur when the method "parent(...)" exits.

Does anybody know what I might be doing wrong or if I'm doing something that isn't possible at all.


int CombinedTreeModel::rowCount(const QModelIndex &parent) const
{
QStandardItem *item = getItem(parent);
if (item == rootItem) {
return rootItem->child.size();
}
return item->rowCount();
}

int CombinedTreeModel::columnCount(const QModelIndex &parent) const
{
return 1;
}

bool CombinedTreeModel::rootContains(QStandardItem *child) const
{
for (int i = 0; i < rootItem->child.size(); i++) {
if (child == rootItem->child.at(i)) {
return true;
}
}
return false;
}

QVariant CombinedTreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();

if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();

QStandardItem *item = getItem(index);

return item->data(index.column());
}

Qt::ItemFlags CombinedTreeModel::flags(const QModelIndex &index) const
{
return getItem(index)->flags();
}

QModelIndex CombinedTreeModel::parent ( const QModelIndex & index ) const
{
if (!index.isValid())
return QModelIndex();

QStandardItem *childItem = getItem(index);
QStandardItem *parentItem = childItem->parent();

// parentItem == rootItem
if (rootContains(childItem)) {
return QModelIndex();
}

return createIndex(parentItem->row(), 0, parentItem);
}

QModelIndex CombinedTreeModel::index( int row, int column, const QModelIndex & parent ) const
{
if (parent.column() > 0)
return QModelIndex();

QStandardItem* parentItem = getItem(parent);
QStandardItem* childItem ;

if (parentItem == rootItem) {
childItem = rootItem->child.at(row);
} else {
childItem = parentItem->child(row);
}

if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}

QStandardItem *CombinedTreeModel::getItem(const QModelIndex &index) const
{
if (index.isValid()) {
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
if (item) return item;
}
return rootItem;
}