模型视图(01):【纲】Model View Tutorial[官翻]

文章目录

  • 1、介绍
    • 1.1 标准小部件
    • 1.2 模型/视图的改善
    • 1.3 模型/视图小部件概述
    • 1.4 在表单和模型之间使用适配器
  • 2. 一个简单的模型/视图应用程序
    • 2.1 一个只读的表
    • 2.2 使用角色扩展只读示例
    • 2.3 表格单元格内的时钟
    • 2.4 设置行、列表头
    • 2.5 最小的编辑示例
  • 3.中间的话题
    • 3.1 TreeView
    • 3.2处理选定项
    • 3.3 预定义的模型
    • 3.4 代理
    • 3.5 通过模型测试进行调试
  • 4. 额外信息的良好来源
    • 4.1 Books
    • 4.2 Qt Documentation

Model/View Tutorial

每个UI开发人员都应该了解ModelView编程,而本教程的目标就是为您提供一个易于理解的关于这个主题的介绍。

表、列表和树小部件是 GUI 中经常使用的组件。这些小部件有两种不同的方式来访问它们的数据。传统的方法涉及到包含存储数据的内部容器的小部件。这种方法非常直观,但是,在许多重要的应用程序中,它会导致数据同步问题。第二种方法是模型/视图编程,其中小部件不维护内部的数据容器。它们通过标准化接口访问外部数据,从而避免了数据重复。乍一看,这似乎很复杂,但一旦深入了解,它不仅容易掌握,而且模型/视图编程的许多好处也会变得更加清晰。

img 视图类对外部数据(模型)进行操作 img QListWidget QlistView img QtreeWidget Qtreeview img QComboBox作为传统小部件工作 QComboBox也可以用作视图类

1.4 在表单和模型之间使用适配器

在表单和模型之间有适配器可以派上用场。

我们可以直接在表本身中编辑存储在表中的数据,但是在文本字段中编辑数据要舒服得多。没有直接对应于模型/视图的数据与视图分离的小部件来操作一个值而不是数据集(QLineEdit 、QCheckBox…),因此我们需要一个适配器来将表单连接到数据源。

QDataWidgetMapper是一个很好的解决方案,因为它将表单小部件映射到表行,并且使为数据库表构建表单变得非常容易。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XRDOzZPr-1607992128752)(https://doc.qt.io/qt-5/images/widgetmapper.png)]

另一个适配器示例是QCompleter。Qt有QCompleter,用于在Qt小部件中提供自动补全功能,如QComboBox和(如下所示)QLineEdit。QCompleter使用一个模型作为它的数据源。

模型视图(01):【纲】Model View Tutorial[官翻]

(file source: examples/widgets/tutorials/modelview/1_readonly/main.cpp)

我们有常用的main()函数:

下面是有趣的部分:我们创建一个MyModel的实例并使用tableView.setModel(&myModel);将它的指针传递给tableView。

tableView会调用接收到的指针的方法来找出两件事:

  • 应该显示多少行和列。
  • 应该在每个单元格中打印什么内容。

模型需要一些代码来响应这两点。

我们有一个表数据集,所以让我们从QAbstractTableModel开始,因为它比更通用的QAbstractItemModel更容易使用。

行数和列数由MyModel::rowCount()和MyModel::columnCount()提供。当视图必须知道单元格的文本是什么时,它调用方法MyModel::data()。用参数索引指定行和列信息,角色设置为Qt::DisplayRole。其他角色将在下一节中介绍。在我们的示例中,生成了应该显示的数据。在真实的应用程序中,MyModel将有一个名为MyData的成员,它作为所有读写操作的目标。

这个小示例演示了模型的被动性质。模型不知道何时使用它或需要哪些数据。它只是在视图每次请求数据时提供数据。

当模型的数据需要更改时,会发生什么视图如何意识到数据已更改并需要再次读取模型必须发出信号,表明单元格的范围发生了变化。这将在第2.3节中演示。

2.2 使用角色扩展只读示例

除了控制视图显示什么文本之外,模型还控制文本的外观。稍微改变模型,得到如下结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b9w8Mwxz-1607992128754)(https://doc.qt.io/qt-5/images/readonlytable_role.png)]

实际上,除了data()方法之外,不需要改变任何东西来设置字体、背景颜色、对齐方式和复选框。下面是产生上述结果的data()方法。不同之处在于,这次我们使用参数int role根据其值返回不同的信息。
(file source: examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp)

每个格式化属性都将通过对data()方法的单独调用从模型中请求。role参数用于让模型知道被请求的属性:

enum Qt::ItemDataRole Meaning Type
Qt::DisplayRole 文本 QString
Qt::FontRole 字体 QFont
BackgroundRole 单元格背景的画刷 QBrush
Qt::TextAlignmentRole 文本对齐方式 enum Qt::AlignmentFlag
Qt::CheckStateRole QVariant()强制使用复选框,
复选框设置Qt::Checked
或Qt::Unchecked
enum Qt::ItemDataRole

请参阅Qt名称空间文档以了解关于Qt::ItemDataRole enum功能的更多信息。

现在我们需要确定使用独立模型如何影响应用程序的性能,因此让我们跟踪视图调用data()方法的频率。为了跟踪视图调用模型的频率,我们在data()方法中放置了一条调试语句,该语句将登录到错误输出流上。在我们的小示例中,data()将被调用42次。每次将光标悬停在字段上时,data()将再次被调用——每个单元格调用7次。这就是为什么在调用data()和缓存昂贵的查找操作时,确保数据可用非常重要。

2.3 表格单元格内的时钟

img

我们仍然有一个只读表,但这次内容每秒都在变化,因为我们显示的是当前时间。

少了什么东西使时钟滴答作响。我们需要每秒钟告诉视图时间已经改变,需要再次读取它。我们用计时器来做这个。在构造函数中,我们将其间隔设置为1秒,并连接其超时信号。

对应的槽如下:

来源:hitzsf

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年11月12日
下一篇 2020年11月12日

相关推荐