5

I am having some trouble with my QStandardItemModel. What I want to do is add a list to my model, and when the list is updated, I pass the new list in the parameter, clear the old model and add the new list. This sounds simple enough but i'm coming across a bug that i can't figure out. When i add the first list to the model there is no problem, but when i add the second one, the first one is successfully deleted (I can see that in the console) but then the application crashes.

Here is my code :

void MyModel::updateList(QList<QStandardItem*> list)
{

    // Delete current model

    int rows = rowCount();
    for (int i = 0 ; i < rows ; i++)
    {
        if(item(0)->hasChildren())
        {
            int children = item(0)->rowCount();
            for (int j = 0 ; j < children ; j++)
            {
                QString name = item(0)->child(0)->accessibleText();
                qDebug()<<(name + QLatin1String("\tremoved"));
                item(0)->removeRow(0);
            }
        }
        QString itemRemoved = item(0)->accessibleText();
        qDebug()<<(itemRemoved + QLatin1String("\tremoved"));
        removeRow(0);
    }


    // Add new list to model

    for(int j=0 ; j<list.count() ; j++)
    {
        appendRow(list[j]);
        qDebug()<< (list[j]->accessibleText() + tr(" ADDED"));
    }

    printf("List UPDATED \n");
}

Obviously i have tried using the method clear(); instead of deleting row by row but it has the same result.

I don't understand why this code doesn't work.

If somebody can shed some light on the matter i would be very grateful.

Simpsons
  • 476
  • 1
  • 7
  • 17
  • Where exactly (and with what message) does it crash? Also, you should avoid using C-style output (`printf`) in C++ ;) – SingerOfTheFall Apr 24 '14 at 13:09
  • There is no message, it just crashes at the first `appendRow()` in the for loop that adds the new list. I actually found that out by placing one `printf` before and one after this line and realising that only the first was printed to the console – Simpsons Apr 24 '14 at 13:17
  • How you items hierarchy looks like? You remove sub items, but add only top level items. – vahancho Apr 24 '14 at 13:18
  • It's worth noting that using `clear();` does exactly the same thing that you are doing manually (well, it also sets the `rowcount` and `colcount` to 0, which you don't), so using it is not what causes the problem. Can you show how do you fill in the model for the first time? – SingerOfTheFall Apr 24 '14 at 13:27
  • Yes that is true. That is because the list in the parameter is of `QStandardItem`. Whilst constructing this new list, i append subitems to top level items, hence, when i add them to the model, i only need to add the top level items and the subitems are added automatically (i know this works because the first list I add is constructed this way and works fine, it is only after i delete the first list and try to add the second that i have a problem) – Simpsons Apr 24 '14 at 13:29
  • @SingerOfTheFall I have tried using `clear();` but it crashes in exactly the same place. This is how I fill the model the first time, i send a list in the parameter and it is added. – Simpsons Apr 24 '14 at 13:33
  • Well, your code looks ok as it is. It's most likely that after you clear the model, it's internal state is somehow messed up (i.e. not really fully cleared), so adding new items causes it to crash. What if you try to append to `invisibleRootItem()` instead of the model itself? – SingerOfTheFall Apr 24 '14 at 13:36
  • No, unfortunately i have already tried this and obtained the same result :( – Simpsons Apr 24 '14 at 13:42
  • This is another case in point why you **absolutely, positively** need an [SSCCE](http://www.sscce.org). We'll be going in circles until you post a minimal example that actually compiles. – Kuba hasn't forgotten Monica Apr 25 '14 at 15:07

2 Answers2

8

The following code is in PyQt, however it's very similar to what you need:

model.removeRows( 0, model.rowCount() )
Garjy
  • 467
  • 5
  • 12
0

The problem was coming from the fact that i was adding the items from the input list directly to the new list. As the input list was created in a different class the parent of the items in it was different and when trying to delete them from the new list it made the application crash.

I resolved the issue by creating the new list from new items and just taking the text() of the old list :

void MyModel::updateList(QList<QStandardItem*> list)
{
    clear();

    for(int i=0 ; i<list.count() ; i++)
    {
        QStandardItem *l_item = new QStandardItem(list[i]->text());
        l_item->setEditable(false);
        l_item->setCheckable(true);
        appendRow(l_item);
        for (int j = 0 ; j<list[i]->rowCount() ; j++)
        {
            QStandardItem *l_subItem = new QStandardItem(list[i]->child(j)->text());
            l_subItem->setEditable(false);
            l_subItem->setCheckable(true);
            l_item->appendRow(l_subItem);
        }
    }
}

This meant that i had to run through the list of children in the input list as pointed out in one of the previous comments because by creating new items i needed to re-append them.

Thanks for all the help

Simpsons
  • 476
  • 1
  • 7
  • 17