05-1_Qt 5.9 C++ Development Guide_Model/View Structure Basics (Basic Principles; Data Model; Trying Components; Proxy)

Model/View(模型/视图) 结构是 Qt 中用界面组件显示与编辑数据的一种结构,视图 (View)是显示和编辑数据的界面组件,模型 (Model) 是视图与原始数据之间的接口。The typical application of the Model/View structure is in database applications, for example, a data table in the database can be displayed and edited in an OTableView component.
The main view components are QListView, QTreeView and QTableView. The QListWidget, QTreeWidget and QTableWidget introduced in Chapter 4 belong to these three classes respectively. They do 便利类not use the data model, but directly store the data in each item of the component.

This chapter introduces the principles of Model/View structure, including QListView, QTreeView, QTableView view components, and usage of model classes such as QStringListModel and OStandardItemModel.

Model/view introduction and use (Model/view Programming) in Qt is a framework mode with advantages:

  • When processing larger data sets, each component performs its own duties without degrading performance;
  • A Model can be mapped to multiple views, so that the same data can be viewed in different ways;
  • If the storage of the underlying data source changes, we only need to deal with the Model

1 Basic Principles of Model/View

A very important function of GUI applications is for users to edit and modify data on the interface, typically such as database applications.数据库应用程序中,用户在界面上执行各种操作,实际上是修改了界面组件所关联的数据库内的数据。

Separating interface components from edited data and connecting them through data sources is a better way to deal with interface and data. Qt uses the Model/View structure to handle this relationship, and the basic structure of Model/View is shown in the figure below. The functions of each part are as follows.

insert image description here

  • Data (Data) is actual data, such as a data table in a database or SQL query results, a StringList in memory, or a disk file structure, etc.
  • A view or view component (View) is an interface component on the screen. The view obtains the model index (model index) of each data item from the data model, obtains the data through the model index, and then provides it to the interface component (no proxy is required when it is only displayed) 显示数据. Qt provides some ready-made data view components, such as QListView, QTreeView and QTableView, etc.
  • The model or data model (Model) communicates with the actual data and provides the data interface for the view components. It extracts the required content from raw data for display and editing by view components. There are some predefined data models in Qt, such as QStringListModel can be used as the data model of StringList, QSglTableModel can be used as the data model of a data table in the database.

Since the data source and the display interface are separated through the Model/View structure, a data model can be displayed in different views, and special view components can be designed without modifying the data model.

  • In the Model/View structure, the Delegate function is also provided. The Delegate function allows the user to customize the data interface (a proxy is required 显示和编辑方式。when displaying and editing is required). In a standard view component, the Delegate function displays a data. When the data is edited, the Delegate communicates with the data model through the model index and provides an editor for editing data, usually a QLineEdit component.

Models, views, and delegates communicate using signals and slots. When the source data changes, the data model emits a signal to notify the view component; when the user operates the data on the interface, the view component emits a signal to represent the operation information; when editing the data, the agent emits a signal to inform the data model and the view component editor of the state.

2 Data Model

All data models (Model) based on item data are based on the QAbstractItemModel class, which defines the interface for view components and agents to access data. The data does not need to be stored in the data model, the data can be other classes, files, databases or any data source. The hierarchical structure of several main classes related to the data model in Qt is shown in the figure below.

insert image description here

The abstract classes in the figure cannot be used directly, and need to be inherited by subclasses to implement some pure virtual functions. Qt provides some model classes for item data processing, the common ones are shown in the table below.

insert image description here

The three models of the database will be introduced later. If the existing model classes cannot meet the requirements, you can inherit from QAbstractItemModel, QAbstractListModel or QAbstractTableModel to generate your own customized data model classes.

3 View Components

The view component (View) is the interface component that displays the data of the data model, and the view components provided by Qt are as follows.

  • QListView: Used to display single-column list data, suitable for one-dimensional data operations.
  • QTreeView: Used to display tree-structured data, suitable for operations on tree-structured data.
  • QTableView: used to display tabular data, suitable for the operation of two-dimensional tabular data.
  • QColumnView: Use multiple QListViews to display the tree hierarchy, and one layer of the tree structure is displayed with an OListView.
  • QHeaderView: A view component that provides row headers or column headers, such as row headers and column headers of QTableView.

When the view component displays data,只需调用视图类的 setModel()函数,为视图组件设置一个数据模型就可以实现视图组件与数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。

Introduced earlier QListWidget, QTreeWidget and QtableWidget 3 components that can be used for data editing. These three classes are called convenience classes, and they are subclasses of three view classes respectively, and their hierarchical relationship is shown in the figure below

insert image description here

Several view classes for the Model/View structure inherit directly from QAbstractItemView, while convenience classes inherit from the corresponding view classes.

The data of the view component class adopts a separate data model, and the view component does not store data. The convenience class creates an item for each node or cell of the component, and uses the item to store data, format settings, and so on. Therefore, the convenience class does not have a data model. It actually integrates the functions of the data model in the form of items, thus binding the interface to the data. Therefore, the convenience class lacks the ability to flexibly process large data sources and is suitable for displaying and editing small data.

4 agents

The agent (Delegate) is to provide an editor for editing data on the view component. For example, when editing the data of a cell in the table component, the default is to use a QLineEdit edit box. The agent is responsible for obtaining the corresponding data from the data model, then displaying it in the editor, and saving it to the data model after modifying the data.
QAbstractItemDelegate is the base class of all proxy classes, as an abstract class, it cannot be used directly. One of its subclasses, QStyledItemDelegate, is the proxy class used by Qt's view components by default.

For some special data editing requirements, such as only allowing input of integers, it is more appropriate to use a QSpinBox as a proxy component, and it is better to use a QComhoBox as a proxy component when selecting data from the list. At this time, you can inherit from QStyledItemDelegate to create a custom proxy class.

5 Some concepts of Model/View structure

5.1 Basic structure of Model/View

In the Model/View structure, the data model provides a standard interface for view components and agents to access data. In Qt, all data model classes are inherited from QAbstractItemModel. Regardless of how the underlying data structure organizes data, subclasses of QAbstractItemModel represent data in a table hierarchy. View components use this rule to access data in the model, but the form presented to users is different.
The figure below shows three common manifestations of the data model.不管数据模型的表现形式是怎么样的,数据模型中存储数据的基本单元都是项(item),每个项有一个行号、一个列号,还有一个父项(parent item)。在列表和表格模式下,所有的项都有一个相同的顶层项 (root item): 在树状结构中,行号、列号、父项稍微复杂一点,但是由这 3 个参数完全可以定义一个项的位置,从而存取项的数据。

insert image description here

5.2 Model index

In order to ensure that the data representation is isolated from the data access method, the concept of model index is introduced into the data model. Each data accessed through the data model has a model index, and both view components and proxies use the model index to obtain data.
OModelIndex A class representing a model index. The model index provides a temporary pointer to data access, used to extract or modify data through the data model. Model indexes are ephemeral because the structure of the data organized within the model can change at any time. If you need to use a persistent model index, use the OPersistentModelIndex class.

5.3 Row and column numbers

The basic form of the data model is tabular data defined by rows and columns, but this does not mean that the underlying data is stored in a two-dimensional array. The use of rows and columns is just a regulation for the convenience of interaction between components. Data can be accessed through the row number and column number of the model index.

To get a model index, 3 parameters must be provided: row number, column number, model index of the parent. For example, for the three data items A, B, and C in the Table Model in the figure above, the code to obtain their model indexes is:

QModelIndex indexA = model->index(00QModelIndex());
QModelIndex indexB = model->index(11QModelIndex());
OModelIndex indexC = model->index(21QModelIndex());

In the function that creates the model index, you need to pass the row number, column number, and the model index of the parent. For list and table mode data models, the top-level node is always represented by QModelIndex().

5.4 Parents

When the data model is a list or a table, it is more intuitive to use row numbers and column numbers to store data. The parent item of all data items is the top-level item; when the data model is a tree structure, the situation is more complicated (in the tree structure, items are generally called nodes). A node can have a parent node, or it can be the parent node of other nodes. When constructing the model index of a data item, the correct row number, column number, and parent node must be specified.

In the Tree Model above, the parent nodes of node A and node C are top-level nodes, and the code to obtain the model index is:

QModelIndex indexA = model->index(00OModelIndex());
OModelIndex indexC = model->index(21QModelIndex());

However, the parent node of node B is node A, and the model index of node B is generated by the following code:

QModelIndex indexB = model->index(10,indexA);

5.5 Roles

When setting data for an item of the data model, it can be given the data of the role (item role) of different items. For example, the item data class of the data model class QStandardItemModel is QStandardItem, and its function for setting data is:

void QStandardItem::setData(const QVariant &value,int role= Qt::UserRole + 1)

Among them, value is the data that needs to be set, and role is the role to set the data. An item can have data in different roles, for different occasions.

role is the enumeration type of Qt:ItemDataRole, which has multiple values. For example, Qt:DisplayRole is a character string displayed in the view component, Qt:ToolTipRole is a mouse tip message, and Qt.:UserRole can customize data. The standard role for items is Ot::DisplayRole.

It is also necessary to specify a role when obtaining data of an item to obtain data of different roles.

QVariant QStandardItem::data(int role = Qt::UserRole + 1) const

Defining data for the different roles of an item tells view components and delegate components how to display the data. For example, in the figure below, the item's DisplayRole data is the displayed string, DecorationRole is the attribute used to decorate the display, and TolTipRole defines the mouse tip information. Different view components may interpret and display various role data differently, and may also ignore certain role data.

insert image description here

The use of convenience classes QListWidget, QTreeWidget and QTableWidget has been introduced earlier. The following articles will introduce the basic usage of the Model/View structure, including the use of Qt's predefined QstringListModel, OFileSystemModel, OStandardItemModel and view components QListView, QTableView, and QTreeView. It also introduces how to design and use custom agents. The use of Mode/View involving the database will be introduced separately in the database chapter.

6. Better Model/View introduction video: Qt 16: Model/View Introduction and Usage (Model/View Programming) ; Qt 17: Model/View Programming Example (Model/View Programming) (not watched) ; Qt 18: Model View Programming Example (not watched) , video blogger blog address

Guess you like

Origin blog.csdn.net/Dasis/article/details/131796129