1.概述
QT5的模型视图结构主要包括模型(Model)、视图(View)和委托(Delegate)三个部分。
-
模型(Model):模型是数据的抽象表示,负责存储和管理数据。它可以是自定义的数据结构,也可以是继承自QAbstractItemModel类的模型类。模型类通过提供一组接口函数来提供数据的访问、修改、插入和删除等功能。
-
视图(View):视图用于显示模型中的数据,并与用户进行交互。常见的视图类有QTreeView、QListView和QTableView等。视图根据模型的数据结构和视图类的特点,将数据以树形、列表或表格的形式进行显示。
-
委托(Delegate):委托用于控制视图中的单元格的显示和编辑行为。可以通过自定义委托类继承自QAbstractItemDelegate类来实现。委托类提供了一组接口函数,用于自定义单元格的显示和编辑行为,如绘制、编辑、大小调整等。
模型-视图结构的工作原理如下:
-
模型:模型负责存储和管理数据,提供接口函数供视图访问和修改数据。当数据改变时,模型会发出相应的信号告知视图进行更新。
-
视图:视图根据模型的数据结构将数据以树形、列表或表格的形式进行显示。视图负责显示模型中的数据,并处理用户的交互操作。当用户对视图进行操作(如点击、编辑等),视图会将相应的操作通知给模型进行数据的修改。
-
委托:委托用于控制视图中的单元格的显示和编辑行为。视图在显示或编辑单元格时,会调用委托类的接口函数。委托类可以根据需要,自定义单元格的显示和编辑行为,如自定义绘制、编辑控件等。
通过模型-视图结构,可以将数据和界面进行有效地分离,使得数据和界面的变动互不干扰。同时,QT5提供了丰富的模型类、视图类和委托类,可以根据需要灵活地进行组合和定制,以满足不同的应用需求。
模型/视图类使用
在QT5中,可以使用预定义的模型和视图类,也可以自定义模型和视图类。下面分别介绍如何使用预定义的模型和视图类以及如何自定义模型和视图类。
使用预定义的模型和视图类:
- 创建模型对象:可以使用QStandardItemModel、QSqlTableModel、QSqlQueryModel等预定义的模型类创建模型对象。例如:
cpp
QStandardItemModel *model = new QStandardItemModel(parent);
- 填充模型数据:使用模型对象的函数来填充数据,比如setItem()、setRowCount()、setColumnCount()等。例如:
cpp
model->setItem(row, column, new QStandardItem("data"));
- 创建视图对象:可以使用QTreeView、QListView、QTableView等预定义的视图类创建视图对象。例如:
cpp
QTreeView *view = new QTreeView(parent);
- 设置模型:将模型对象设置给视图对象,使用setModel()函数。例如:
cpp
view->setModel(model);
- 显示视图:将视图对象添加到布局或窗口中,使其显示出来。例如:
cpp
layout->addWidget(view);
自定义模型和视图类:
- 创建自定义模型类:继承QAbstractItemModel类,实现其纯虚函数,根据数据的结构和特点,自定义模型类的数据存储和访问方式。例如:
cpp
class MyModel : public QAbstractItemModel {
// ...
};
- 创建自定义视图类:继承QTreeView、QListView、QTableView等预定义的视图类,根据需要可以重写其函数,实现特定的显示和交互方式。例如:
cpp
class MyView : public QTreeView {
// ...
};
- 创建模型对象和视图对象:根据自定义的模型类和视图类,创建对象。例如:
cpp
MyModel *model = new MyModel(parent);
MyView *view = new MyView(parent);
- 设置模型:将模型对象设置给视图对象,使用setModel()函数。例如:
cpp
view->setModel(model);
- 显示视图:将视图对象添加到布局或窗口中,使其显示出来。例如:
cpp
layout->addWidget(view);
以上是使用预定义的模型和视图类、自定义模型和视图类的一般步骤。根据具体需求,可以根据QT5的文档和示例代码,进一步了解和使用模型和视图类的功能和特性。
2.模型(Model)
模型(Model)是在MVC(Model-View-Controller)设计模式中的一部分,用于存储和管理数据。在QT5中,模型提供了一种用于组织和操作数据的方式,可以将数据与视图分离,使其更易于管理和显示。
在QT5中,有几种预定义的模型类可以使用:
-
QAbstractItemModel:是所有模型类的基类,定义了一些纯虚函数,需要子类来实现,以提供自定义的数据存储和访问方式。
-
QStandardItemModel:是一个使用QStandardItem对象作为数据项的模型类。每个数据项都包含一个文本和可选的图标等属性。
-
QSqlTableModel:是一个与数据库表对应的模型类,可以用于直接访问数据库中的数据。
-
QSqlQueryModel:是一个基于SQL查询的模型类,可以通过执行SQL查询来获取数据并显示。
自定义模型类的步骤如下:
-
继承QAbstractItemModel类,创建自定义模型类。
-
在自定义模型类中实现以下纯虚函数:
- rowCount():返回模型的行数。
- columnCount():返回模型的列数。
- data():返回给定索引的数据。
- index():返回具有给定行和列的索引。
- parent():返回给定索引的父索引。
-
根据需要,可以实现其他函数来支持模型的编辑、插入、删除等操作。
使用模型的步骤如下:
-
创建模型对象,可以是预定义的模型类对象,也可以是自定义模型类的对象。
-
通过模型对象的函数来填充数据,比如setItem()、setData()等。
-
将模型对象设置给视图对象,使用setModel()函数。
-
显示视图对象,将其添加到布局或窗口中。
-
可以通过模型对象的函数来访问和操作数据,比如获取数据、修改数据等。
模型的使用可以实现数据的存储、排序、过滤和显示等功能,提高应用程序的灵活性和可扩展性。可以根据具体需求,选择合适的模型类或者自定义模型类来实现数据的管理和显示。
3.视图(View)
在QT中,有多种视图可以用于显示模型中的数据,包括但不限于以下几种:
-
QTableView:QTableView是QT中最常用的视图之一,它以表格的形式展示数据。每个单元格都可以编辑,并且支持排序、过滤、选择等功能。
-
QTreeView:QTreeView是以树状结构展示数据的视图。通过树状的父子关系,可以方便地展示层级关系的数据。
-
QListView:QListView是以列表形式展示数据的视图。它提供了横向和纵向的滚动条,适用于较长的数据列表。
-
QGraphicsView:QGraphicsView是用于显示基于图形场景(QGraphicsScene)的视图。它支持复杂的图形和图像的显示,可以进行缩放、旋转、拖拽等操作。
除了上述常用视图外,QT还提供了其他一些视图类,如QColumnView(用于显示列的视图)、QHeaderView(显示表格或列表的标题栏)等。
使用视图的步骤如下:
-
创建视图对象,如QTableView、QTreeView等。
-
将模型对象设置给视图对象,使用setModel()函数。
-
可以通过视图对象的函数来设置或获取视图的外观,如设置表头、背景色、选择模式等。
-
可以通过视图对象的信号和槽来实现与用户的交互,如点击、双击、选择等操作。
-
将视图对象添加到布局或窗口中,显示出来。
通过使用适合的视图来展示数据,可以提供良好的用户体验,并且可以根据需求进行定制和扩展。在QT中,视图和模型之间的关联是通过模型-视图架构(Model-View)来实现的,因此可以很方便地修改数据和显示方式,而不会影响彼此。
4.代理
在QT5的模型/视图结构中,代理(Delegate)是一种用于自定义视图的外观和行为的机制。代理可以用来修改某些或全部的视图单元格的显示、编辑和交互方式,从而实现更灵活的界面效果。
QT中提供了以下几种常用的代理类:
-
QStyledItemDelegate:这是QT默认的代理类,提供了默认的外观和行为。可以通过继承QStyledItemDelegate来自定义代理。
-
QItemDelegate:这是一个更通用的代理类,它提供了更多的功能和设置选项,如自定义绘制、编辑器的创建等。
-
QAbstractItemDelegate:这是一个抽象类,需要继承并实现其虚函数才能创建自定义的代理。
使用代理的步骤如下:
-
创建代理对象,如QItemDelegate或自定义的代理类对象。
-
将代理对象设置给视图对象,使用setItemDelegate()函数。
-
可以通过代理对象的函数来设置或获取不同视图单元格的外观和行为,如设置对齐方式、背景色、编辑器等。
-
可以通过代理对象的虚函数来自定义视图单元格的绘制和编辑行为,如绘制复杂的图标、自定义编辑器的显示和验证等。
下面是一个使用代理的示例代码:
// 创建代理对象
QItemDelegate* delegate = new QItemDelegate(this);
// 将代理对象设置给视图对象
tableView->setItemDelegate(delegate);
// 自定义某个单元格的外观和行为
delegate->setAlignment(Qt::AlignCenter, Qt::DisplayRole);
// 自定义某个单元格的编辑器
QSpinBox* spinBox = new QSpinBox(tableView);
delegate->setEditorData(spinBox, QModelIndex());
通过使用代理,我们可以对不同的视图单元格进行个性化的定制,使界面更加灵活和富有交互性。