c++qtqtreeviewqstandarditemmodelqstandarditem

QTreeView with 2 columns for each entry


I want to create a QTreeview with 2 columns. That is no problem so far. I made this with the following code:

QStandardItemModel *model = new QStandardItemModel(0,2); 
ui->treeView->setModel(model);

Now I want to fill this TreeView. To do that I created a QStandardItem with 0 rows and 1 column.

QStandardItem *root = new QStandardItem(0,2);

After that I added data to this root item.

root->setText("name");
root->setData("value", 1);

At the end I am adding the model to a QTreeView

ui->treeView->setModel(model);

The problem is, that value is not displayed in the second column of the QTreeView. I am sure, that the reason is, that the second column of the model is not the same as the second column of the root item.

But how to solve this problem?


Solution

  • You don't need to specify the number of rows or columns, just concentrate on adding the elements to your model and it will care about the internal details.

    In this minimal example, a model is created, filled with three parents (external loop), with 3, 2 and 1 children each (internal loop). That is, the model will have a total of (1 + 3) + (1 + 2) + (1 + 1) = 9 rows, and two columns per row for the children (name and data), but only one for the parents (only name, note the 0 added as second value).

    QStandardItemModel * model = new QStandardItemModel;
    
    QStandardItem * root = model->invisibleRootItem();
    
    QList<QStandardItem*> rowItems;
    for (int i = 0; i < 3; ++i) {
        QString parentName = QString("Parent #%1").arg(i + 1);
        QStandardItem* parent = new QStandardItem(parentName);
        rowItems << parent << 0;
        root->appendRow(rowItems);
        rowItems.clear();
    
        for (int j = 0; j < 3 - i; ++j) {
            QString childName = QString("Child %1-%2").arg(i + 1).arg(j + 1);
            QStandardItem* item = new QStandardItem(childName);
            int content = (i + 1) * (j + 1) * 2700;
            QStandardItem* itemData = new QStandardItem(QString("%1").arg(content));
            rowItems << item << itemData;
            parent->appendRow(rowItems);
            rowItems.clear();
        }
    }
    
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Data"));
    
    ui->treeView->setModel(model);
    

    Note that the steps this example uses are:

    1. Create the model
    2. Fill the model row by row. Each row is a list of QStandardItem elements (rowItems), and you append the row to its parent item (or to a root item if they are first level elements).
    3. Set up additional characteristics of the model (headers in this case)
    4. Attach the model to any view that it is needed.

    Note that I did not use model->beginInsertRows(...) and model->endInsertRows() since the model modifications are done before attaching the model to the views. If you modify the model content after attaching it to any view, you should use those calls. Otherwise, keep in mind that any index that you might be using could become invalid after the model is updated.