PDA

View Full Version : Forming a tree of QWidgetItems



IndigoJo
16th September 2010, 09:44
Hi everyone,

I'm trying to use QTreeWidgetItem to display a hierarchy of categories for a blog, as is found in Wordpress. I thought I could create a QMap of QListWidgetItem pointers with the category ID as the key, then iterate through the list and add each item to its relevant parent, like so:



// Now add all the categories into a big list
for( b = 0; b < catsToDisplay; b++ ) {
catItem = new QTreeWidgetItem;
id = mainCatList.at( b ).firstChildElement( "categoryId" ).text();
//qDebug() << "id =" << id;
catItem->setText( 0, decodeXmlEntities( mainCatList.at( b ).firstChildElement( "categoryName" ).text() ) );
description = decodeXmlEntities( mainCatList.at( b ).firstChildElement( "description" ).text() );
if( !description.isEmpty() )
catItem->setStatusTip( 0, description );
catItem->setData( 0, Qt::UserRole, QVariant( id ) );
catItem->setData( 0, 33, QVariant( false ) ); // i.e. not primary category until required
catItems[id] = catItem;
}
qDebug() << "done the top-level categories";
// Now assign each category to its respective parent, and make a list of
// top-level items
Q_FOREACH( QTreeWidgetItem *item, catItems ) {
thisId = item->data( 0, Qt::UserRole ).toString();
qDebug() << "now doing" << thisId;
if( thisId != "0" && catItems.contains( thisId ) ) {
qDebug() << "not a top-level";
thisItem = catItems[thisId];
qDebug() << "got item" << thisItem->data( 0, Qt::UserRole ).toString();
Q_ASSERT( thisItem != 0 );
thisItem->addChild( item );
}

if( thisId == "0" ) {
qDebug() << "top-level";
topLevelCatItems.append( item );
}
qDebug() << "have now done" << thisId;
}


The full method can be found here (http://bitbucket.org/IndigoJo/qtm-1x/src/b2da4958862e/EditingWindow_ResponseHandlers.cc) at my Bitbucket hg repo.

The program halts at line 25 -- where it tries to add a child QTreeWidgetItem to one that doesn't have a parent. My aim in doing this was to build up a tree of items which could all be added, in one go, to the QTreeWidget, because it seems more efficient than having to run several recursive loops, and also because the user wouldn't have to watch the tree appear bit by bit.

It doesn't crash or segfault; it just stops and you have to kill the process.

Can anyone tell me what I'm doing wrong here? It doesn't say in the documentation that you can't add a child to a parentless item.

Regards,

Matt

wysota
16th September 2010, 12:34
Hi Matthew,

try running your app under control of a debugger and when it halts, break it (Ctrl+C in gdb) and print a backtrace. Make sure to have Qt debugging symbols available so that the debugger can look into Qt routines as well.

IndigoJo
16th September 2010, 20:26
OK ... this is what I got when I used the debug info:



Program received signal SIGINT, Interrupt.
QTreeWidgetItemPrivate::propagateDisabled (this=<value optimized out>, item=0xb1e120)
at itemviews/qtreewidget.cpp:1658
1658 itemviews/qtreewidget.cpp: No such file or directory.
in itemviews/qtreewidget.cpp
(gdb)
(gdb) backtrace
#0 QTreeWidgetItemPrivate::propagateDisabled (this=<value optimized out>, item=0xb1e120)
at itemviews/qtreewidget.cpp:1658
#1 0x00007ffff78994aa in QTreeWidgetItem::insertChild (this=0xb1e120, index=0, child=
0xb1e120) at itemviews/qtreewidget.cpp:1928
#2 0x00007ffff78995fb in QTreeWidgetItem::addChild (this=0xb1e120, child=0xb1e120)
at itemviews/qtreewidget.cpp:1882
#3 0x000000000049fce8 in EditingWindow::wp_getCategories (this=0xb8d210, response=...)
at /home/indigojo/hg/qtm-1.4/EditingWindow_ResponseHandlers.cc:600

wysota
16th September 2010, 20:48
There is nothing in Qt's code that would cause a freeze.
You could switch to frame #1 and print values of this->text() and child->text() to see what items are being processed. It could get you some insight whether the program indeed freezes at the elements you think it freezes at.

I'm trying to analyze your algorithm but honestly I'm having a hard time understanding it.