31

Qt Model/View教程——只读Table

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484266&%3Bidx=1&%3Bsn=84cf446ed1fd845322ac735a9cdf394c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,可以点个在看,让它可以帮助到更多老铁~

一直想学习Qt Model/View,最终还是看的官方教程,现在将官方教程重新在梳理下。

每个UI开发人员都应该了解 Model/View 编程!可见 Model/ViewUI 编程中的重要性!

那它为什么这么重要呢?

Table,、 ListTree widgetsGUI 中经常使用的组件。   这些小部件可以通过两种不同的方式访问其数据。   传统方式部件 使用内部容器进行存储数据。,这种方法非常直观,但是,在许多特别 的应用程序中,它会导致数据同步问题。   第二种方法是模型 / 视图编程,其中小部件不维护内部数据容器。   他们通过标准化接口访问外部数据,因此避免了数据重复。   乍一看,这似乎很复杂,但是一旦仔细研究,不仅容易掌握,而且模型 / 视图编程的许多好处也变得更加清晰。

整个教程的目录如下:

标准部件 和模型 / 视图部件之间的区别

表单和模型之间的适配器

开发一个简单的模型 / 视图应用程序

预定义模型

中级主题:

Tree views

Selection

Delegates

Debugging with model test

一、  概述

模型 / 视图是一种用于将数据与处理数据集的小部件中的视图分离的技术。 标准窗口小部件并非旨在将数据与视图分离,这就是为什么 Qt 具有两种不同类型的窗口小部件的原因。 两种类型的小部件外观相同,但是它们与数据的交互方式不同。

1.  标准部件

Table Widget 是用户可以更改的数据元素的 2D 部件   可以通过读写表小部件提供的数据元素将表小部件集成到程序中。   此方法非常直观,在许多应用程序中很有用,但是使用标准表窗口部件显示和编辑数据库表可能会出现问题。   数据的两个副本必须协调一致:一个在小部件外部;另一个在小部件 部。    开发人员 必须负责同步两个数据副本   除此之外,数据的紧密耦合使编写单元测试更加困难

2. Model/View

Model/View 使用了更加灵活的体系结构来提供 解决方案。Model/View消除了标准小部件可能发生的数据一致性问题,   而且 Model/View还可以让同一数据源在多个视图上进行显示变得更加方便;因为一个Model可以传递给许多Views   最重要的区别是 Model/View部件不在表单内部 存储数据。   实际上, Model/View直接对 您的数据进行操作。   由于视图类不知道数据的结构,因此需要提供包装器以使数据符合 QAbstractItemModel 接口 【译者注:这就是为什么要 setMode   View使用该接口进行读取和写入数据, 实现 QAbstractItemModel 的类的任何实例都称为模型 【译者注:什么是 Model   一旦 View接收到指向模型的指针,它将读取并显示其内容并成为其编辑器【 译者注: setModel 后, View 自动读取数据并显示 】。

二、  一个简单的 Model/View 应用程序

如果要开发Model/View应用程序,应该从哪里开始?   我们建议从一个简单的示例开始【译者注:我表示非常赞同!】 ,并逐步扩展它,这使得 了解架构变得容易得多。   事实证明,在调用 集成好的接口前尝试详细了解Model/View 体系结构对于许多开发人员来说并不方便。   从具有演示数据的简单 Model/View 应用程序开始要容易得多。   试试看!   只需将以下示例中的数据替换为您自己的数据即可

以下是 7 个非常简单和独立的应用程序,它们展示了模型 / 视图编程的不同方面。   可以在 examples/widgets/tutorials/modelview 目录中找到源代码

1.  只读 Table

我们从使用 QTableView 来显示数据的应用程序开始。 之后我们将添加编辑功能。

只读table,效果如下:

RNRJ3y2.png!web

我们创建 MyModel 的实例并使用 tableView.setModel (& myModel   将其指针传递给 tableView   tableView 将调用它收到的指针获得以下信息:

应显示多少行和多少列

每个单元格应显示什么内容

Model需要一些代码来对此做出响应。我们有一个表数据集,因此让我们从 QAbstractTableModel开始,因为它比更通用的QAbstractItemModel 更加易于使用。【 译者注:以后会更加了解这两个类的

mymodel.h 代码:

#include <QAbstractTableModel>


class MyModel : public QAbstractTableModel

{

Q_OBJECT

public:

MyModel(QObject *parent);

int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE ;

int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;

};

QAbstractTableModel 需要实现三种抽象方法

mymodel.cpp 代码:

#include "mymodel.h"


MyModel::MyModel(QObject *parent)

:QAbstractTableModel(parent)

{

}


int MyModel::rowCount(const QModelIndex & /*parent*/) const

{

return 2;

}


int MyModel::columnCount(const QModelIndex & /*parent*/) const

{

return 3;

}


QVariant MyModel::data(const QModelIndex &index, int role) const

{

if (role == Qt::DisplayRole)

{

return QString("Row%1, Column%2")

.arg(index.row() + 1)

.arg(index.column() +1);

}

return QVariant();

}

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

这个小例子说明了模型的被动性质。  该模型不知道何时使用它或需要哪些数据。   每次视图请求时,它仅提供数据

当需要更改模型数据时会发生什么?  视图如何认识到数据已更改并且需要再次读取? 该模型必须发出一个信号,该信号指示已更改了哪些单元格范围。   这将在第 2.3 节中演示

总结:

之前由于项目需要,使用过Qt的文件系统模型,当时直接用的现成的程序,那会儿就很不明白为什么一定要 setModel ,设置完后又会自己显示。教程看到这之后,终于明白了。所以我比较喜欢知道为什么这么做、这么做应该会有一个什么样的结果。

最后祝大家元旦快乐!2020,体验全力做一件事的幸福与艰辛!

欢迎关注公众号:

MZzeIjR.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK