PDA

View Full Version : QStandardItemModel, parent / child to form tree structure



Nightfox
7th January 2010, 23:15
I'm getting a little stuck here guys!

I'm using a QStandardItemModel (mymodel) for storing hierarchical data. At the point of filling the model with data I do not necessarily know the parent/child relationship in the dataset and the user need to be able to change that after data load. So I've divided the loading process in two steps. (1) Load the model from a database source and (2) create tree structure on the model.

Load the model



void MainWindow::LoadMyModel()
{
--Code snipped has been cut down to save space
while (query.next())
{
for(int col=0; col < rec.count(); col++)
{
QStandardItem *item = new QStandardItem();
item->setData(query.value(col),Qt::DisplayRole);
mymodel->setItem(row,col,item);
}
++row;
}
}

Create tree structure

void MainWindow::createtreestructure()
{
QStandardItem *parentItem = mymodel->invisibleRootItem(); //rootItem
QStandardItem *oldparentItem ;//placeholder for Item->parent()
for(int row = 0; row < mymodel->rowCount(); ++row ) {
QStandardItem *item = mymodel->item(row,parent_acc_id);//Grap Item
int parentid = item->data(Qt::DisplayRole).toInt();//this integer determines the (new) parent of Item
oldparentItem = static_cast<QStandardItem *>(item->parent()); //cast parent in order to use QStandardItem::takeChild
if(oldparentItem){
oldparentItem->takeChild(item->row(),item->column());//remove (but do not delete) Item from model to avoid double entry
}
if( parentid >0 ) { //ParentKeys has been declared earlier as QMap<int,QStandardItem*> ParentKeys
main->ParentKeys.value(parentid)->setChild(0,item); //Asign child to new parent
} else {
parentItem->setChild(0,item); //no parentid was found = assign to rootItem
}
}
}


All this seems pretty straight forwarded but I'm simply not able to assign the QStandardItem to a new/other parent Item. I keep getting errors like 'QStandardItem::setChild: Ignoring duplicate insertion of item 0x94a6a70'.

An other approach would be to subclass an abstractmodel (like in the simply treeview example shipped with Qt) to get the necessary functionality but it seems like QStandardItemModel has all the functionally required to create and maintain a tree structure.

Initially it wouldn't be a problem to load the model and apply the tree structure from the beginning for instance by using the example provided by Qt...


QStandardItemModel model;
QStandardItem *parentItem = model.invisibleRootItem();
for (int i = 0; i < 4; ++i) {
QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
parentItem->appendRow(item);
parentItem = item;
}

...but I still need to be able to rearrange the parent/child relationship without going through the trouble of creating my own treemodel.

Is there anyone who has experience with QStandardItemModel on how to assign parent/child relationship or how to rearrange parent/child after the model has been created? I'm running out of ideas!

Thanks

numbat
8th January 2010, 07:53
The problem may be that you are not removing the item when it has no parent. Try removing parentless items with mymodel->takeItem

Nightfox
8th January 2010, 17:01
An item is never parentless. You can't see it in the code snippet above but what Qt is doing behind the scenes is to assign items to the invisibleRootItem of the QStandardItemModel if it's not added to the model through another item (appendRow). That's what I'm trying to catch (see line 3 in the second code snippet). But I think you're right in the sense that it's the assigning/reassigning part that is the key to solving my problem.