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
 

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