当前位置:网站首页>QT learning notes QT model/view
QT learning notes QT model/view
2022-07-29 06:13:00 【Q-Stark】
Catalog
Preface
Due to work needs , To implement a small data management system . Ben wanted to pick it up QT Skill ideas , Study QT Operation of model view .
One 、Qt Introduction to model view structure
Model / View structure , Still separate the data from the way it is presented to the user , But it provides a simple framework based on the same principle . This separation allows it to display the same data in several different views , And implement new types of views , Without changing the underlying data structure . In order to deal with user input flexibly , The concept of delegation is introduced . The advantage of introducing delegation in this framework is : It allows project data display and custom editing .
- The model communicates with the data source , In this architecture, an interface is provided for other components . The nature of communication depends on the type of data source and the implementation of the model .
- The view gets the model index from the model , These all refer to data items . By providing a model index for the model , Views can retrieve data items from data sources .
- In the standard view , Delegate data items . When an item is edited , Delegates communicate directly with the model using the model index .
Model / View / Entrusted communication
The signal of the model : Inform the view about changes in the data maintained by the data source .
Signal of view : Provides project information about user interactive display .
The signal of entrustment : Tell the status of the model and view editor when editing .
Two 、Qt Model
Concept
All models are based on QAbstractItemModel class . This class defines an interface that uses views and delegates to access data . The data itself does not have to be stored in the model , It can be in a data structure or a separate class 、 file 、 database 、 Or some other application components .
QAbstractItemModel Provides an interface for data , It has enough flexibility to process tables 、 list 、 Data view in tree form . However , When implementing a new list and table like data structure model ,QAbstractListModel and QAbstractTableModel Classes are a better starting point , Because they provide the default implementation of appropriate common functions . These classes can derive subclasses , A model used to provide support for specific kinds of lists and tables .
Qt Some ready-made models are provided , It can be used to process data items :
- QStringListModel: For storing simple QString List items of .
- QStandardItemModel: Manage more complex tree structures , Each of these items can contain any data .
- QFileSystemModel: Provides file and directory information about the local file system .
- QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel: Using the model / View conventions to access the database .
In the model / In the view structure , The model provides a standard interface for views and delegates to access data . stay Qt in , The standard interface consists of QAbstractItemModel Class definition . No matter what underlying data structure the data items are stored in ,QAbstractItemModel The data represented by all subclasses of is regarded as a hierarchical structure containing view items . The view uses this Convention to access the data items in the model , However, it does not limit the way in which this information is communicated to users .
Model indexes
To ensure that the presentation and acquisition of data are separated , Introduce the concept of model index . We can get every piece of information through the model index . Views and delegates use these indexes to request displayed data items .
therefore , Only the model needs to know how to get the data , The types of data managed by models can be quite universally defined . Model indexes contain a pointer to the model that created them , This prevents confusion when dealing with multiple models .
QAbstractItemModel *model = index.model();
The model index provides temporary reference information , And can be used to retrieve or modify data through the model . Because the model may reorganize its internal structure , The index of the model may become invalid , Not suitable for storage . If you need to refer to a piece of information for a long time , You must create a persistence model index . This provides a reference for keeping the model up-to-date . The temporary model index is created by QModelIndex Class provides , The persistence model is indexed by QPersistentModelIndex Class provides .
Get the model index corresponding to the data item , Three attributes must be formulated in the model : One line number 、 A column number , And the model index of the parent .
The ranks of
Under the basic framework , The model can be accessed as a simple form , The data items can be located by row and column numbers . This does not mean that the underlying structure of the data is also a sequence structure ; Row and column numbers are only used to facilitate the communication between components . We can retrieve the information of the data item corresponding to the model through the row and column number .
Parent
When using data in a table or list view , The idealized way is that the model provides a class table interface to the data items ; Row and column numbers are accurately mapped to the data items corresponding to the view . However , A structure like a tree view requires the model to expose a more flexible interface . therefore , Each data item can also be the parent of another table , In much the same way , The top-level data item in a tree view can contain another data item list .
When requesting an index of a model item , You must provide some information about the parent node of the data item . Outside the model , The only way to access a data item is through a model index , Therefore, the parent node index also needs to provide :
QModelIndex index = model->index(row, column, parent);
The top-level nodes in the model will usually QModelIndex()
Specify as parent node .
Data item role
The data items in the model can play different roles for other components , Allow different types of data for different situations . for example ,Qt::DisplayRole
A string that can be displayed as text in the access view . Usually , Items containing data are used for several different roles , And the standard role is Qt::ItemDataRole
Definition .
We can request data item data from the model through the corresponding model index , And get the desired data type by specifying a role :
QVariant value = model->data(index, role);
3、 ... and 、Qt View
Concept
In the model view architecture , Views are used to get data items from the model , And show the user . The structure shown by the view does not have to be completely consistent with the model , It can even be completely different from the underlying data storage structure .
Views usually manage the overall layout of the data obtained from the model . They can render individual data items by themselves , Or use proxy to handle rendering and editing functions . In addition to displaying data , Views also deal with navigation between data items and some aspects of data item selection . These views also implement basic user interface functions , Such as context menus and drag and drop . Views can provide default editing functions for data items , You can also provide a custom editor with delegates .
Views can be built without models , But you must provide the model first , Then useful information can be displayed . View by using selections
Track the data items selected by the user , These options can be maintained separately for each view , Or share among multiple views .
Some views ( Such as QTableView and QTreeView) The title and data items can be displayed at the same time . These are also defined by the view class QHeaderView Realization . Titles usually access the same model as the view containing them . They use QAbstracItemModel::headerData()
Function to retrieve data from the model , Title information is usually displayed in the form of labels . It can be downloaded from QHeaderView Subclass the new title in the class , To provide more specialized labels for views .
Use existing views
Qt Three ready-made view classes are provided , They display the data in the model in a way familiar to most users .QListView You can display items in a model as a simple list , Or in the form of classic icon view .QTreeView Displays items in the model as a hierarchy of lists , Allows deep nested structures to be represented in a compact way .QTableView Display the items in the model in the form of a table , Very similar to the layout of a spreadsheet application .
For most applications , The default function of the standard view shown above should be sufficient . They provide basic editing functions , And it can be customized to meet the needs of a more professional user interface .
Using the model
The method of using the model is very simple , Build a model , Pass in some data , Build a view to show the content of the model .
view->setModel(model);
Operation selected
The operation mechanism of the selected view is QItemSelectionModel
Class provides . All standard views have their own default selection model , And interaction . The selection model of view can be through selectionModel()
Function to obtain , Can also pass setSelectionModel()
Function to replace the selection model .
Four 、Qt entrust
And MVC Different modes , The model view design does not include a complete separate component to manage user interaction . Usually, the view is responsible for presenting the data of the model to the user , With the function of processing user input . In order to have some flexibility in the way of obtaining input , Interactions can be performed by delegates . These components provide input functions , It is also responsible for rendering individual item data items in some views . The standard interface for controlling delegates is QAbstractItemDelegate
Definition in class .
By implementing paint()
and sizeHint()
function , We expect our clients to present their own content . However , Simple based on widget Can be entrusted by QItemDelegate
instead of QabstratemDelegate
Subclassing implementation , And use the default implementation of these functions .
The delegate editor can be created by using widget To manage the editing process , It can also be achieved by directly handling events .
Use existing delegates
Qt The standard view provided uses QItemDelegate
The instance of provides editing function . The default implementation of the delegate interface is for each standard view (QListView、QTableView and QTreeView) Render data items in the usual style .
All standard roles are handled by the default delegation used by the standard view .
The delegation used by the view is itemDelegate()
The function returns .setItemDelegate()
Function allows you to install custom delegates for standard views , This function is required when setting delegates for custom views .
A simple custom delegate
This delegate uses a Qspinbox To provide editing functions , It is mainly used to make the model display integers .
Our delegation is inherited from QStyledItemDelegate
, Because we don't need to implement the display function by ourselves , However, we still need to provide functions to manage editing controls .
class SpinBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
Note that the editor is not constructed in the constructor of the delegate , Build the editor only when needed .
Provide an editor
QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QSpinBox *editor = new QSpinBox(parent);
editor->setFrame(false);
editor->setMinimum(0);
editor->setMaximum(100);
return editor;
}
Note that we don't need to keep the pointer of the editor component , Views are automatically recycled when they are no longer in use .
We install the default event filter of delegation to the editor to ensure that it can provide the standard editing shortcuts expected by users .
The view ensures that the data and geometry settings of the editor are correct by calling the functions we define later . We can create different editors according to the model index provided by the view . for example , If we have a list of integers and a list of strings , We can go back to QSpinBox or QLineEdit, It depends on the column being edited .
Delegates must provide functions to copy model data into the editor . In this case , The code is as follows :
void SpinBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}
In this case , We know that the editor is a spinbox, But we can provide different editors for different types of data in the model , under these circumstances , We need to convert the editor to the appropriate type before accessing its member functions .
Submit data to the model
When the user finishes editing , The view will call setModelData()
The function enables the delegate to store the edited value in the model .
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();
model->setData(index, value, Qt::EditRole);
}
Because the view is managing the editor , We only need to update the model with the content provided by the editor . In this case , We make sure that spin box Is the latest , And use the specified index to update the model with the values it contains .
The standard QItemDelegate
Class emits closeEditor()
Signal notification view . This view ensures that the editor widget is closed and destroyed . In this case , We only provide simple editing functions , So we never need to send this signal .
All operations on data are performed through QAbstracteModel The interface provided performs . This makes the delegate basically independent of the data type it handles , But in order to use some types of editor widgets , Some assumptions must be made . In this case , We assume that the model always contains integer values , But we can still use this delegate for different types of models , because QVariant Provides reasonable default values for unexpected data .
Update editor geometry
The delegate is responsible for managing the geometry of the editor . When creating an editor and changing the size or position of items in a view , Geometry must be set . Fortunately, , The view provides all necessary geometry information in the view option object .
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
Editor's note
After editing , Delegates should provide hints to other parts about the results of the editing process , And provide tips that are helpful for subsequent editing operations . This is done by issuing closeEditor()
Signal . This is by default QItemDelegate The event filter is responsible for , We are building spin box Install it on spin box On .
5、 ... and 、 Creating models
Model / The functional separation between view components allows the creation of models that can take advantage of existing views . This approach allows us to use standard graphical user interface components ( Such as QListView、QTableView and QTreeView) Present data from various sources .QAbstracteModel
Class provides a sufficiently flexible interface , Data sources that support the arrangement of information in a hierarchical structure , It is allowed to insert 、 Delete 、 Modify or sort data . It also supports drag and drop operations .QAbstractListModel
and QAbstractTableModel
Class provides interface support for simpler non hierarchical data structures , And it's easier to use as a starting point for simple list and table models .
The design model
When creating a new model for an existing data structure , It is important to consider which type of model should be used to provide interfaces to data . If the data structure can be expressed as an item list or table , Then you can put QAbstractListModel
or QAbstractTableModel
Subclass , Because these classes provide suitable default implementations for many functions . However , If the underlying data structure can only be represented by hierarchical tree structure , Then it is necessary to QAbstractItemModel
Subclass .
No matter what form the underlying data structure takes , It is usually best to supplement the standard in the special model QabstracteModel API, Make it more natural to access the underlying data structure . This makes it easier to fill the model with data , But other generic models are still allowed / The view component uses standard API Interact with it .
When implementing the model , It's important to remember ,QAbstracteModel
It doesn't store any data on its own , It only provides one interface , The view uses this interface to access data .
Read only model
For the smallest read-only model , You only need to implement a few functions , Because most interfaces have default implementations .
For a read-only model, except for the constructor of the model , We only need to implement the following functions :rowCount()
Returns the number of rows in the model , If necessary, you also need to implement the column number function columnCount()
,data()
Returns the data item corresponding to the specified model index . Usually we also realize headerData()
function , Provide tree view and table view with some content that can be displayed in its title .
If the model is hierarchical , We still need to achieve index()
and parent()
function .
Editable model
Editable models need to be based on read-only models , Modify the data()
function , And implement two additional functions : flags()
and setData()
.
Add a declaration to the definition of the class :
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
Delegate to check whether the data item is editable before creating the editor . The model must let the delegate know that its data items are editable . So , We return the corresponding flag for each data item in the model ; under these circumstances , We will enable all data items , Make them both selectable and editable :
Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
Please note that , We don't have to know how the delegate performs the actual editing process . We just need to provide a way for delegates to set data in the model . This is through setData()
Functionally implemented :
bool Model::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
m_data.replace(index.row(), value.toString());
emit dataChanged(index, index, {
role});
return true;
}
return false;
}
After setting the data , The model must let the view know that some data has changed . This is done by sending dataChanged()
It's done with signals .
Line operation
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
Search for
It is often useful to find items in the project view , Whether as a developer or as a service to users . All three item view Convenience classes provide a general findItems() function , Make it as consistent and simple as possible .
According to from Qt::MatchFlags
The condition specified by the value selected in , Search for items through the text they contain . We can use findItems() Function to get a list of matches :
QTreeWidgetItem *item;
QList<QTreeWidgetItem *> found = treeWidget->findItems(
itemText, Qt::MatchWildcard);
foreach (item, found) {
treeWidget->setItemSelected(item, true);
// Show the item->text(0) for each item.
}
If the item in the tree contains the text given in the search string , Then the above code will cause these items to be selected . This mode can also be used in lists and tables .
边栏推荐
- 1、 What is the difference between transfer learning and fine tuning?
- 噪声传感器工作原理是什么?
- 新能源共享充电桩管理运营平台
- [target detection] 6. SSD
- Typical cases of xdfs & China Daily Online Collaborative Editing Platform
- Chongqing Avenue cloud bank, as a representative of the software industry, was invited to participate in the signing ceremony of key projects in Yuzhong District
- 华为云14天鸿蒙设备开发-Day5驱动子系统开发
- Set automatic build in idea - change the code, and refresh the page without restarting the project
- QT学习笔记-Qt Model/View
- 5、 Image pixel statistics
猜你喜欢
随机推荐
Migration learning notes - adaptive component analysis
ML17-神经网络实战
ML7自学笔记
CNOOC, desktop cloud & network disk storage system application case
Pytorch Basics (Introductory)
Tf.get in tensorflow_ Detailed explanation of variable() function
HAL库学习笔记-12 SPI
2021-06-10
Dust and noise monitoring system
HAL库学习笔记-10 HAL库外设驱动框架概述
基于51单片机ADC0808的proteus仿真
倾角传感器精度校准检测
6、 Pointer meter recognition based on deep learning key points
How to perform POC in depth with full flash distribution?
PyTorch的数据读取机制
1、 Combine multiple txt files into one TXT file
基于STC51:四轴飞控开源项目原理图与源码(入门级DIY)
Beijing Baode & taocloud jointly build the road of information innovation
四、One-hot和损失函数的应用
Hal library learning notes-10 overview of Hal library peripheral driver framework