Qt: set columns in treeView

gartenriese picture gartenriese · Feb 1, 2014 · Viewed 8.1k times · Source

How can I implement this code I have for a qTreeWidget for a qTreeView?

for (const auto & i : names) {
    QTreeWidgetItem * item = new QTreeWidgetItem(ui->treeWidget);
    item->setText(0, QString::fromStdString(i));
    ui->treeWidget->addTopLevelItem(item);
    const std::unordered_map<std::string, double> map = m_reader.getMapFromEntry(i);
    for (const auto & j : map) {
        QTreeWidgetItem * item2 = new QTreeWidgetItem();
        item2->setText(0,QString::fromStdString(j.first));
        item2->setText(1,QString::number(j.second));
        item->addChild(item2);
    }

}

I have a model and a treeView, like this:

m_model = new QStandardItemModel(m_reader.getAllNames().size(),2,this);
ui->treeView->setModel(m_model);

I tried this, but that only shows one column:

QStandardItem * parentItem = m_model->invisibleRootItem();
for (const auto & i : names) {
    QStandardItem * item = new QStandardItem(QString::fromStdString(i));
    parentItem->appendRow(item);
    const std::unordered_map<std::string, double> map = m_reader.getMapFromEntry(i);
    for (const auto & j : map) {
        QList<QStandardItem *> rowItems;
        rowItems << new QStandardItem(QString::fromStdString(j.first));
        rowItems << new QStandardItem(QString::number(j.second));
        item->appendRow(rowItems);
    }
}

With the treeWidget, I had so set the columnCount, like this:

ui->treeWidget->setColumnCount(2);

But treeView does not have a method like this.

So, to summarize: How can I implement a TreeView with more than one column?

EDIT:
To clarify, I want something like this:

|-A
| |-B-C
| |-D-E

where A is the parent and B,C,D,E the children, with B,D being in column 0 and C,E in column 1.

Hope this helps!

Answer

Frank Osterfeld picture Frank Osterfeld · Feb 1, 2014

To support multiple columns, the model must contain data for multiple columns. So in some sense, columns are a property of the model, not the view. Views then can decide to hide or rearrange certain columns (For example, a QListView always only shows the first column, while one can hide or reorder columns in a QTableView).

As you use QStandardItemModel, its documentation should give a few hints how to create multiple columns.

E.g., look at this example from the documentation:

 QStandardItemModel model(4, 4);
 for (int row = 0; row < 4; ++row) {
     for (int column = 0; column < 4; ++column) {
         QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
         model.setItem(row, column, item);
     }
 }

It creates a model with 4 initial rows and columns each, and then fills it with items via setItem().

Alternatively, you can pass a list of items to QStandardItemModel::appendRow(), with an item for each column:

QList<QStandardItem*> items;
items.append(new QStandardItem(tr("One"));
items.append(new QStandardItem(tr("Two"));
model->appendRow(items);

This adds a new row with "One' in the first column and "Two" in the second. For even more ways to deal with multiple columns, see the QStandardItemModel docs.

Note: QTreeView expects the same number of columns on all levels of the hierarchy, so one should fill rows with empty items for the unused columns if need be.