Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

Righe vuote in QStandardItemModel, tentanto un approccio non ricorsivo al popolamento di un albero (QT 5.9)



  • Buongiorno a tutti,
    Dovendo popolare una struttura ad albero a partire da un database (QStandardItemModel e QTreeView), ho tentato un approccio non ricorsivo, dato che il metodo ricorsivo era davvero molto lento.

    Il problema dell'approccio che ho scelto, è che mi lascia moltissime righe vuote nella QTreeView oltre ad una sfilza di messaggi di debug tipo questo: "QStandardItem::insertRows: Ignoring duplicate insertion of item 0x652e380". Fra l'altro sembra impossibile riuscire poi a cancellare le righe vuote: treeModel->removeRows(1, treeModel->rowCount()); non funziona.

    il codice è molto semplice, fondamentalmente popolo una QList di oggetti contenenti ognuno un record della query al database. ogni nodo è univocamente identificato dal campo id, e può avere un solo padre. Nel primo ciclo while popolo la QList e genero tutti i puntatori ai QStandardItem; in seguito con due cicli for annidati, per ogni elemento nella QList, cerco il padre, e una volta trovato, con appendRow, creo la relazione padre/figlio; a questo punto esco dal ciclo, in quanto ogni nodo può avere un solo padre. C'è anche un if che identifica il nodo radice e lo aggiunge all'invisibleRootItem del modello:

    mainwindow.h

    //[...]
    struct item
        {
            int id;
            int parent;
            int aggregation;
            int sequence;
            QString code;
            QString description;
            QStandardItem * node;
        };
        QList<item> tree;
        QStandardItemModel * treeModel;
    //[...]
    

    mainwindow.cpp

    //[...]
    while (query.next())
            {
                item current;
                current.id = query.value(0).toInt();
                current.parent = query.value(1).toInt();
                current.aggregation = query.value(2).toInt();
                current.sequence = query.value(3).toInt();
                current.code = query.value(4).toString();
                current.description = query.value(5).toString();
                current.node = new QStandardItem(query.value(5).toString());
                tree.append(current);
            }
    for (int i=0;i<tree.length();i++)
            {
                for (int j=0;j<tree.length();j++)
                {
                    if (tree[i].parent == 0)
                    {
                        treeModel->invisibleRootItem()->appendRow(tree[i].node);
                    }
                    else if (tree[j].id == tree[i].parent)
                    {
                        tree[j].node->appendRow(tree[i].node);
                        break;
                    }
                }
            }
    //[...]
    

    è un peccato che si creino tutte queste righe vuote, perché il codice gira davvero molto velocemente. Circa un secondo per caricare ventimila nodi.

    A qualcuno è già capitato qualcosa di simile?
    Grazie mille.
    Saluti.


  • Qt Champions 2018

    for (int i=0;i<tree.length();i++) {
        if (tree[i].parent == 0) {
            treeModel->appendRow(tree[i].node);
            continue;
        }
        for (int j=0; j<tree.length(); j++) {
             if (tree[j].id == tree[i].parent) {
                tree[j].node->appendRow(tree[i].node);
                break;
            }
        }
    }
    


  • @VRonin said in Righe vuote in QStandardItemModel, tentanto un approccio non ricorsivo al popolamento di un albero (QT 5.9):

    for (int i=0;i<tree.length();i++) {
    if (tree[i].parent == 0) {
    treeModel->appendRow(tree[i].node);
    continue;
    }
    for (int j=0; j<tree.length(); j++) {
    if (tree[j].id == tree[i].parent) {
    tree[j].node->appendRow(tree[i].node);
    break;
    }
    }
    }

    Sapevo che era un errore stupido il mio... non credevo così tanto stupido... Grazie mille, ora funziona perfettamente.


Log in to reply