Creating Qt models for tree views

2020-06-03 01:15发布

问题:

I'm writing an application in Qt (with C++) and I need to represent an object structure in a tree view. One of the ways to do this is to create a model for this, but I'm still quite confused after reading the Qt documentation about the subject.

The "structure" I have is pretty simple - there's a Project object that holds Task objects in a std::vector container. These tasks can also hold child tasks.

I've already written methods to read & write these projects to/from XML files using Qt's XML classes.

Is there any more documentation or "recommended reading" for creating models from scratch? How do you recommend I start implementing this?

回答1:

As an alternative to what was said by Virgil in a comment to the question, you could use QStandardItemModel class for your model and just build your tree using this class. Below is an example:

QStandardItemModel* model = new QStandardItemModel();

QStandardItem* item0 = new QStandardItem(QIcon("test.png"), "1 first item");
QStandardItem* item1 = new QStandardItem(QIcon("test.png"), "2 second item");
QStandardItem* item3 = new QStandardItem(QIcon("test.png"), "3 third item");
QStandardItem* item4 = new QStandardItem("4 forth item");

model->appendRow(item0);
item0->appendRow(item3);
item0->appendRow(item4);
model->appendRow(item1);

ui->treeView->setModel(model);

When the UI (view) is destroyed, delete model. Documentation:

  • https://doc.qt.io/qt-5/qstandarditemmodel.html
  • https://doc.qt.io/qt-5/qstandarditem.html


回答2:

The basic trick to get this working is really to get the model to data structure mapping right. Something that might seem hard, but needn't be.

First, using the QAbstractItemModel::createIndex to build model indexes, you can refer to your own data structure through the pointer or uint32 that you can add to the index, depending on which instance of createIndex that you choose to use.

Second, having the structure clear in mind (as you seem to have), it is quite easy to write the parent and index functions. The key here is to understand that the model root is an unintialized QModelIndex instance. I.e. QModelIndex::isValid() == false indicates root.

Third, if you go multi-column, remember that only the first column has children.

Fourth, to check that you do things the expected way, do use the ModelTest class. It monitors and checks your model, so that you follow the conventions that the Qt model view classes expect.