为树形视图创建Qt模型

17

我正在使用Qt(带有C ++)编写应用程序,需要在树形视图中表示对象结构。其中一种方法是为此创建模型,但是在阅读了有关Qt文档后,我仍然感到相当困惑。

我拥有的“结构”非常简单 - 有一个Project对象,它在std :: vector容器中保存Task对象。这些任务还可以包含子任务。

我已经编写了使用Qt的XML类从XML文件读取和写入这些项目的方法。

是否有更多的文档或“推荐阅读”,以创建自定义模型?您建议我如何开始实施呢?


对于 QTreeView 的新手来说,主要的挑战在于理解 index()parent()。我之前写过一篇关于这个问题的文章:http://www.hardcoded.net/articles/using_qtreeview_with_qabstractitemmodel.htm。示例代码是用 Python 编写的,但原则是相同的。 - Virgil Dupras
2个回答

19

作为对Virgil在评论中提到的内容的替代方案,您可以使用QStandardItemModel类作为您的模型,并使用该类构建您的树。以下是一个示例:

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);
当UI(视图)被销毁时,删除model。文档:

谁负责QStandardItemModel(model)和创建的QStandardItems?即当ui->treeView被销毁时,我是否应该手动删除模型和项? - AAEM
1
@AAEM 从QStandardItem[Model]文档中并不清楚,但是看起来appendRow会接管这些项(尝试两次附加第二个项将失败)。与所有其他setModel调用一样,视图不会接管模型(以便共享)。您必须在最后删除模型。(使用valgrind和Qt 5.11.2进行验证) - Lekensteyn
这对于简单情况很好。但是让我们假设你无法一次性构建模型(比如,您将第一个项目添加到invisibleRootItem,并向其添加一些行(子节点)。然后您做其他事情(例如解析树下方需要的数据)。然后您想要继续。您必须检索已添加的节点。你该怎么做?您有两种方法:findItems()item()。前者不是为此目的设计的,我发现它不可靠,而后者接受rowcolumn。这是否足以在树中定位节点?当然,在文档中没有答案。 - z33k
未来的问候!10年后,这个答案为我节省了数小时,甚至数天的工作时间。谢谢! - insaner

6
这个工作的基本技巧是正确地将模型映射到数据结构。这可能看起来很难,但实际上并不需要。
首先,使用 QAbstractItemModel::createIndex 来构建模型索引,您可以通过指针或 uint32 引用自己的数据结构,具体取决于您选择使用哪个 createIndex 实例。
其次,如果您已经明确了结构(就像您似乎已经做到了),编写 parentindex 函数非常容易。关键在于要理解模型根是未初始化的 QModelIndex 实例。即 QModelIndex::isValid() == false 表示根。
第三,如果您使用了多列,请记住只有第一列有子项。
第四,为了检查您是否按预期方式执行操作,请使用 ModelTest 类。它会监视和检查您的模型,以便您遵循 Qt 模型视图类所期望的约定。

模型架构的解释非常清晰简单。谢谢! - satishgoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接