QTreeWidget AddChild causes Crash!



  • Hi guys,

    I'm trying to add a child QTreeWidgetItem to a pre-existing Item (which I added through the visual Editor). While I am able to get the correct selection of the item i want to be the parent, whenever i try adding any child items to it, builds fine but then crashes when launched.

    //header file
    QModelIndex InterIndex;
    
    //CPP file
    QTreeWidgetItem *newChild = new QTreeWidgetItem();
    newChild->setText(0, "i am a test Child!");
     
    //Select the correct pre-existsing item
    QItemSelectionModel *InterSel = new QItemSelectionModel(ui->TW_World->model());
    InterIndex = ui->TW_World->model()->index(5,0,QModelIndex());
    InterSel->select(InterIndex, QItemSelectionModel::Select);
    ui->TW_World->setSelectionModel(InterSel);
    
    ui->TW_World->currentItem()->addChild(newChild); // This line causes the crash
    

    Seems everywhere i look my code appears to be right but something is getting messed up, probably something really simple.

    Thanks!


  • Moderators

    Don't create new selection models every time you want to select something. QTreeWidget already has a selection model and you should use that.

    Second thing is that selected and current items are not the same thing. Programatically selecting an item doesn't make it current automatically.

    Third thing is that you have a crash because you never check return values. For example ui->TW_World->currentItem() can return nullptr if there's no current item and then you try to call a method on it, so it crashes.

    One more thing - QTreeWidget is a higher level abstraction over the QTreeView. When using it try not to go to the lower level i.e. don't use model(), QModelIndex or selection model directly. These are lower layer classes useful when using QTreeView directly or implementing your own model.

    Also - you don't need to mess with selection to add a child item at all. Those are two unrelated operations.

    So, to add a child to specific item you would do:

    QTreeWidgetItem* parent_item = ui->TW_World->topLevelItem(5); //returns 6th top level item or nullptr if no such item exists
    if (parent_item)
        new QTreeWidgetItem(parent_item, QStringList("i am a test Child!"));
    

    If you also want to select that item and make it current:

    QTreeWidgetItem* parent_item = ui->TW_World->topLevelItem(5);
    if (parent_item)
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(parent_item, QStringList("i am a test Child!"));
        child->setSelected(true);
        ui->TW_World->setCurrentItem(child);
    }
    

    Btw. Out of curiosity - are you coming from Java or similar language? Your code looks kinda like that.



  • Hi Chris,

    Thank you very much for your help, it works like a charm now! :D

    I'm actually coming from an Old language called Blitz3D and i've been using c++ for just over a year now but still quite new to some aspects of QT. I'm just irritated by the fact the solution was so simple and i managed to over complicate it.

    Once again Thanks!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.