彩票走势图

界面开发框架Qt新手入门教程:可编辑树模型的示例(一)

翻译|使用教程|编辑:颜馨|2023-05-12 13:53:40.583|阅读 152 次

概述:本章讲述Qt小部件:可编辑树模型的示例,欢迎查阅~

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

The Qt Company是Digia Plc旗下的全资子公司。负责所有Qt活动,包括产品开发,商业和开源授权模式以及在开放管理模式下的Qt工程。其许可、支持和服务能力能够和开发者紧密合作以确保他们的Qt项目准时部署,不超预算并拥有竞争优势。

Qt技术交流群:166830288

此示例演示如何实现一个简单的基于项的树模型,该模型可与模型/视图框架的其他类一起使用。

该模型支持可编辑项、自定义标题以及插入和删除行和列的功能。使用这些功能,还可以插入新的子项,这在支持的示例代码中显示。

概述

如模型子类化参考中所述,模型必须为标准模型函数集提供实现:flags()、data()、headerData()、columnCount() 和 rowCount()。此外,分层模型,比如这个,需要提供 index() 和 parent() 的实现。

可编辑模型需要提供 setData() 和 setHeaderData() 的实现,并且必须从其 flags() 函数返回合适的标志组合。

由于这个例子允许改变模型的维度,我们还必须实现insertRows(),insertColumns(),removeRows()和removeColumns()

设计

与简单树模型示例一样,该模型只是充当类实例集合的包装器。每个都旨在保存树视图中一行项目的数据,因此它包含与每列中显示的数据对应的值列表。

由于 QTreeView 为模型提供了面向行的视图,因此很自然地为数据结构选择面向行的设计,该设计将通过模型向此类视图提供数据。尽管这使得树模型不太灵活,并且对于用于更复杂的视图可能不太有用,但它使设计变得不那么复杂,并且更易于实现。

内部项目之间的关系

在设计用于自定义模型的数据结构时,通过 TreeItem::p arent() 等函数公开每个项的父项很有用,因为它将使编写模型自己的 parent() 函数更容易。类似地,像 TreeItem::child() 这样的函数在实现模型的 index() 函数时很有帮助。因此,每个都维护有关其父级和子级的信息,使我们能够遍历树结构。该图显示了实例如何通过其 parent() 和 child() 函数进行连接。

在所示的示例中,可以通过调用其 child() 函数从根项获取两个顶级项 A 和 B,并且这些项中的每一个都从其 parent() 函数返回根节点,尽管这仅针对项 A 显示。

每个都在其私有成员(QVariant 对象列表)中表示的行中存储每一列的数据。由于视图中的每一列和列表中的每个条目之间存在一对一的映射,因此我们提供了一个简单的 data() 函数来读取列表中的条目,并提供了一个 setData() 函数来允许修改它们。与项目中的其他函数一样,这简化了模型的 data() 和 setData() 函数的实现。

我们将一个项目放在项目树的根目录中。此根项对应于空模型索引 QModelIndex(),该索引用于在处理模型索引时表示顶级项的父项。尽管根项在任何标准视图中都没有可见的表示形式,但我们使用其内部 QVariant 对象列表来存储字符串列表,这些字符串将传递给视图以用作水平标题。

通过模型访问数据

在图中所示的情况下,可以使用标准模型/视图 API 获取由 a 表示的信息片段:

QVariant a = model->index(0, 0, QModelIndex()).data();

由于每个项目都包含给定行中每一列的数据片段,因此可以有许多映射到同一对象的模型索引。例如,可以使用以下代码获取 b 表示的信息:TreeItem

QVariant b = model->index(1, 0, QModelIndex()).data();

同样的底层将被访问以获得与b.TreeItem相同行的其他模型索引的信息。

在模型类中,当我们在 index() 和 parent() 实现中使用 QAbstractItemModel::createIndex() 创建相应的模型索引时,我们通过为每个项目传递一个指针来将对象与模型索引相关联。我们可以通过在相关模型索引上调用 internalPointer() 函数来检索以这种方式存储的指针 - 我们创建自己的 getItem() 函数来为我们完成工作,并从我们的 data() 和 parent() 实现中调用它。

当我们控制项目的创建和销毁方式时,存储指向项目的指针很方便,因为我们可以假设从 internalPointer() 获得的地址是有效的指针。但是,某些模型需要处理从系统中的其他组件获取的项,并且在许多情况下,无法完全控制项的创建或销毁方式。在这种情况下,纯基于指针的方法需要辅以保护措施,以确保模型不会尝试访问已删除的项目。

在底层数据结构中存储信息

几段数据作为 QVariant 对象存储在每个实例的成员中。

该图显示了由前两个图中的标签 a、b 和 c 表示的信息片段如何存储在基础数据结构中的项目 A、B 和 C 中。请注意,模型中同一行的信息片段都是从同一项目获取的。列表中的每个元素对应于模型中给定行中每列公开的一条信息。

由于该实现是为与 QTreeView 一起使用而设计的,因此我们对其使用实例的方式添加了限制:每个项目必须公开相同数量的数据列。这使得查看模型保持一致,允许我们使用根项来确定任何给定行的列数,并且仅添加创建包含足够列数数据的项的要求。因此,插入和删除列是耗时的操作,因为我们需要遍历整个树来修改每个项目。

另一种方法是设计类,以便在修改数据项时截断或扩展单个实例中的数据列表。但是,这种“懒惰”的大小调整方法只允许我们在每行的末尾插入和删除列,而不允许在每行的任意位置插入或删除列。

使用模型索引关联项

与简单树模型示例一样,需要能够获取模型索引,找到相应的 ,并返回与其父项和子项对应的模型索引。

在图中,我们展示了模型的 parent() 实现如何使用上图中显示的项获取与调用方提供的项的父项对应的模型索引。

指向项 C 的指针是使用 QModelIndex::internalPointer() 函数从相应的模型索引中获取的。指针在创建时存储在索引内部。由于子项包含指向其父项的指针,因此我们使用其 parent() 函数来获取指向项 B 的指针。父模型索引是使用 QAbstractItemModel::createIndex() 函数创建的,将指向项 B 的指针作为内部指针传递。

Qt Widget组件推荐
  • QtitanRibbon - Ribbon UI组件:是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,QtitanRibbon致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
  • QtitanChart - Qt类图表组件:是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。
  • QtitanDataGrid - Qt网格组件:提供了一套完整的标准 QTableView 函数和传统组件无法实现的独特功能。使您能够将不同来源的各类数据加载到一个快速、灵活且功能强大的可编辑网格中,支持排序、分组、报告、创建带状列、拖放按钮和许多其他方便的功能。
  • QtitanDocking:允许您像 Visual Studio 一样为您的伟大应用程序配备可停靠面板和可停靠工具栏。黑色、白色、蓝色调色板完全支持 Visual Studio 2019 主题!

  • 欢迎下载|体验更多Qt产品

    获取更多信息请咨询  ;Qt技术交流群:166830288


    标签:

    本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


    为你推荐

    • 推荐视频
    • 推荐活动
    • 推荐产品
    • 推荐文章
    • 慧都慧问
    扫码咨询


    添加微信 立即咨询

    电话咨询

    客服热线
    023-68661681

    TOP