QT 模型/视图 编程 委托篇

委托类

 概述

 

  与模型-视图-控制器模式不同,模型/视图设计不包括用于管理与用户交互的完全独立的组件。通常,视图负责向用户表示模型数据,并处理用户输入。为了在获取输入的方式上允许一定的灵活性,交互由委托执行。这些组件提供输入功能,并负责在某些视图中呈现各个项。控制委托的标准接口在QAbstractItemDelegate类中定义。

 

  委托应该能够通过实现paint()和sizeHint()函数来呈现它们自己的内容。然而,简单的基于widget的委托可以子类化QItemDelegate而不是QAbstractItemDelegate,并利用这些函数的默认实现。

 

  委托的编辑器可以通过使用小部件来管理编辑过程,也可以通过直接处理事件来实现。第一种方法将在本节后面介绍,它也将在Spin Box委托示例中显示。

 

Pixelator示例展示了如何创建一个自定义委托来执行表视图的专门化呈现。

  使用一个已存在的委托类

  Qt提供的标准视图使用QItemDelegate的实例来提供编辑功能。这个委托接口的默认实现以每个标准视图的通常样式呈现项目:QListView、QTableView和QTreeView。

所有标准角色都由标准视图使用的默认委托处理。这些解释的方式在QItemDelegate文档中有描述。

视图使用的委托由itemDelegate()函数返回。函数的作用是:为标准视图安装自定义委托,在为自定义视图设置委托时需要使用该函数。

 一个简单的委托

 这里实现的委托使用QSpinBox提供编辑功能,主要用于显示整数的模型。尽管我们为此设置了一个基于整数的自定义表模型,但我们可以轻松地使用QStandardItemModel,因为自定义委托控制数据条目。我们构造一个表视图来显示模型的内容,这将使用自定义委托进行编辑。

 

我们从QStyledItemDelegate子类化委托,因为我们不想编写自定义的显示函数。但是,我们仍然必须提供管理编辑器小部件的功能:

 

 注意,在构造委托时不设置编辑器小部件。我们只在需要时构造编辑器小部件。

提供一个编辑

  在本例中,当表视图需要提供一个编辑器时,它要求委托提供一个适合被修改项的编辑器小部件。createEditor()函数提供了委托设置合适小部件所需的一切:

  注意,我们不需要保留指向编辑器小部件的指针,因为视图负责在不再需要它时销毁它。

  我们在编辑器上安装委托的默认事件过滤器,以确保它提供用户期望的标准编辑快捷方式。可以向编辑器添加其他快捷方式,以允许更复杂的行为;这些将在编辑提示一节中讨论。

  该视图通过调用稍后为这些目的定义的函数来确保编辑器的数据和几何图形被正确设置。我们可以根据视图提供的模型索引创建不同的编辑器。例如,如果我们有一个整数列和一个字符串列,我们可以返回QSpinBox或QLineEdit,这取决于编辑的是哪一列。

  委托必须提供一个函数来将模型数据复制到编辑器中。在本例中,我们读取display角色中存储的数据,并相应地在spin框中设置值。

 

   在本例中,我们知道编辑器小部件是一个自旋框,但是我们可以为模型中不同类型的数据提供不同的编辑器,在这种情况下,我们需要在访问其成员函数之前将小部件转换为适当的类型。

向模型提交数据

  当用户完成对spin框中的值的编辑后,视图通过调用setModelData()函数要求委托将编辑后的值存储在模型中。

  由于视图管理委托的编辑器小部件,所以我们只需要使用提供的编辑器的内容更新模型。在本例中,我们确保spin框是最新的,并使用指定的索引用它包含的值更新模型。

  当视图完成编辑时,标准的QItemDelegate类通过发出closeEditor()信号通知视图。视图确保编辑器小部件已关闭并销毁。在本例中,我们只提供简单的编辑工具,因此我们不需要发出这个信号。

  所有的数据操作都是通过QAbstractItemModel提供的接口来执行的。这使得委托在很大程度上独立于它操作的数据类型,但是为了使用某些类型的编辑器小部件,必须做一些假设。在本例中,我们假设模型始终包含整数值,但是我们仍然可以将此委托用于不同类型的模型,因为QVariant为意外数据提供了合理的默认值。

更新编辑器的几何图形

  委托的职责是管理编辑器的几何图形。在创建编辑器时,以及在更改视图中项的大小或位置时,必须设置几何图形。幸运的是,视图在视图选项对象中提供了所有必要的几何信息。

 

   在本例中,我们仅使用项目矩形中的视图选项提供的几何信息。呈现带有多个元素的项的委托不会直接使用项矩形。它将把编辑器与项目中的其他元素放在一起。

编辑提示

  在编辑之后,委托应该向其他组件提供有关编辑过程结果的提示,并提供有助于任何后续编辑操作的提示。这是通过使用适当的提示发出closeEditor()信号来实现的。这是由默认的QItemDelegate事件过滤器负责的,我们在构建它时将其安装在spin框上。

  旋转框的行为可以调整,使其更友好的用户。在QItemDelegate提供的默认事件过滤器中,如果用户点击Return确认他们在spin框中的选择,则委托将该值提交给模型并关闭spin框。我们可以通过在spin框中安装自己的事件过滤器来改变这种行为,并提供适合我们需要的编辑提示;例如,我们可以使用EditNextItem提示发出closeEditor()来自动开始编辑视图中的下一项。

  另一种不需要使用事件过滤器的方法是提供我们自己的编辑器小部件,可能是为了方便而将QSpinBox子类化。这种替代方法将使我们能够以编写额外代码为代价,更好地控制编辑器小部件的行为。如果您需要自定义一个标准Qt编辑器小部件的行为,则通常更容易在委托中安装事件过滤器。

  委托不需要发出这些提示,但是那些不需要发出提示的将不太容易集成到应用程序中,而且与那些发出提示来支持常见编辑操作的委托相比,它们的可用性更差。

 

posted @ 2020-02-29 19:50  helloc14  阅读(222)  评论(0编辑  收藏  举报