Search code examples
c++qtqt5qtreeviewqstandarditemmodel

Populate QTreeView as parent and child nodes from database


I have data stored in the following columns in the database

|AcName|ActCod|GroupCode|

|parent1| |1|   |0|

|child1|  |101| |1|

|parent2| |2|   |0|

|child2|  |201| |2|

I am using a QTreeView, QStandardItemModel, and QStandardItem to create this treeview however I don't know how to append the child to the parent. I stored QStandardItem items into a QMap but how do I append child nodes to parent and parent nodes to rootNode?

the code.

standardModel = new QStandardItemModel(this);
QStandardItem *rootNode = standardModel->invisibleRootItem();
QSqlQuery *itemqry = new QSqlQuery("SELECT GroupCode, AcName, ActCod from adm_ac");
while(itemqry->next()){
    int groupcode =itemqry->value(0).toInt();
    QString acname = itemqry->value(1).toString();
    int ActCod = itemqry->value(2).toInt();
    QStandardItem *itemmap = new QStandardItem(acname);
    rowItemMap.insert(groupcode, itemmap);

    }
}
 ui->treeView->setModel(standardModel);

the header file.

QStandardItemModel *standardModel;
QStandardItem *acName1;
QStandardItem *acName2;
QMap<int, QStandardItem*> rowItemMap;

Solution

  • Here is an other way to build your tree. This code take care also the case that child nodes were loaded before its parent. The tree will be built in two pass :

    1. Load all items to the map
    2. Build the tree from the map

    EDIT: We use setData() function instead of setProperty since QStardardItem is not QObject derived.

        enum GroupCodeRoleEnum{
            GroupCodeRole = Qt::UserRole + 1001,
        };
    
        while(itemqry->next())
        {
            int groupcode =itemqry->value(0).toInt();
            QString acname = itemqry->value(1).toString();
            int ActCod = itemqry->value(2).toInt();
            QStandardItem *itemmap = new QStandardItem(acname);
    
            itemMap->setData(groupcode, GroupCodeRole );
    
            //map of ActCod to itemmap, not GroupCode
            rowItemMap.insert(ActCod, itemmap) );
    
        } //End of while -- every node were now loaded.
    
        //build the tree
        rowItemMap.insert (0, rootNode ) ;
    
        foreach( QStandardItem * p, rowItemMap.values() ){
            int groupCode = p->data( GroupCodeRole ).toInt();
    
            //find the parent from the map
            if( p != rootNode ){
    
                QMap<int, QStandardItem* >::iterator it = rowItemMap.find( groupCode );
    
                if( it != rowItemMap.end() ){
    
                    QStandardItem* pParent = it.value();
                    pParent->appendRow( p );
                }else {
                    qDebug() << "Parent not exist for groupCode" << groupCode; 
                }
    
            }//nomal node
    
        } //foreach  
    
        ui->treeView->setModel(standardModel);
    

    TEST CODE:

            QStandardItemModel *standardModel = new QStandardItemModel(this);
            QStandardItem *rootNode = standardModel->invisibleRootItem();
    
            //Simulate your while() loop.
            addItem(1, 0, "parent 1");
            addItem(101, 1, "child 1");
            addItem(2, 0, "parent 2");
            addItem(201, 2, "child 2");
    
            //childs were loaded before parents
    
            addItem(301, 3, "child 3");
            addItem(401, 4, "child 4");
            addItem(501, 5, "child 5");
    
            addItem(3, 2, "parent 3");
            addItem(4, 2, "parent 4");
            addItem(5, 2, "parent 5");
    
            //build the tree
            m_map.insert (0, rootNode ) ;
    
            foreach( QStandardItem * p, m_map.values() ){
                int groupCode = p->data( GroupCodeRole ).toInt();
    
                //find the parent from the map
                if( p != rootNode ){
    
                    QMap<int, QStandardItem* >::iterator it = m_map.find( groupCode );
    
                    if( it != m_map.end() ){
    
                        QStandardItem* pParent = it.value();
                        pParent->appendRow( p );
                    }else {
                        qDebug() << "Parent not exist for groupCode" << groupCode;
                    }
    
                }//nomal node
    
            } //foreach
    
            ui->treeView->setModel(standardModel);
        }
    
        void MainWindow::addItem(int Act, int nGroupCode, QString szName)
        {
                QStandardItem *itemmap = new QStandardItem( szName );
    
                itemmap->setData(nGroupCode, GroupCodeRole );
    
                //map of ActCod to itemmap, not GroupCode
                m_map.insert(Act, itemmap);
    
        }
    

    The tree was built :

    enter image description here