为树视图创建 Qt 模型
Posted
技术标签:
【中文标题】为树视图创建 Qt 模型【英文标题】:Creating Qt models for tree views 【发布时间】:2010-12-31 10:51:21 【问题描述】:我正在用 Qt(使用 C++)编写一个应用程序,我需要在树视图中表示一个对象结构。一种方法是为此创建一个模型,但是在阅读了有关该主题的 Qt 文档后,我仍然很困惑。
我拥有的“结构”非常简单——Project
对象在 std::vector
容器中保存 Task
对象。这些任务也可以包含子任务。
我已经编写了使用 Qt 的 XML 类从 XML 文件读取和写入这些项目的方法。
是否有更多文档或“推荐阅读”用于从头开始创建模型?你建议我如何开始实施这个?
【问题讨论】:
对于QTreeView
新手来说,主要挑战是理解index()
和parent()
。我前段时间写过一篇文章:hardcoded.net/articles/… 示例代码是用 Python 编写的,但原理保持不变。
【参考方案1】:
作为 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(模型)和创建的 QStandardItems 的所有权?即当 ui->treeView 被销毁时,我应该手动删除模型和项目吗? @AAEM 从 QStandardItem[Model] 文档中不清楚,但似乎 appendRow 获得了项目的所有权(尝试附加第二个项目两次失败)。与所有其他setModel
调用一样,视图不获取模型的所有权(以方便共享)。您必须在最后删除模型。 (通过 valgrind 和 Qt 5.11.2 验证)
这对于简单的情况非常有用。但是让我们假设您不能一次性构建模型(假设您将第一项添加到 invisibleRootItem
和一些行(子节点)到它。然后您执行其他操作(例如解析树下方所需的数据) ). 然后你想继续。你必须检索已经添加的节点。你会怎么做?你有两种方法:findItems()
和item()
。前者不是为此目的而设计的,我找到了不可靠,后者接受row
和column
。如何在树中定位节点就足够了?文档中当然没有答案。
来自未来的问候! 10 年后,这个答案为我节省了几个小时,如果不是几天的话。谢谢!【参考方案2】:
实现这个工作的基本技巧是让模型正确地映射到数据结构。可能看起来很难,但不一定是这样的事情。
首先,使用QAbstractItemModel::createIndex构建模型索引,你可以通过指针或uint32引用你自己的数据结构,你可以添加到索引中,这取决于你选择使用哪个createIndex实例。
其次,在结构清晰的情况下(如您所见),编写parent
和index
函数非常容易。这里的关键是要了解模型根是未初始化的QModelIndex
实例。 IE。 QModelIndex::isValid() == false
表示root。
第三,如果你去多列,记住只有第一列有子列。
第四,要检查你是否按照预期的方式做事,请使用ModelTest 类。它监视和检查您的模型,以便您遵循 Qt 模型视图类所期望的约定。
【讨论】:
对模型架构的简单解释。谢谢!以上是关于为树视图创建 Qt 模型的主要内容,如果未能解决你的问题,请参考以下文章