给网站做seo的价格,wordpress 快速编辑,济南推广营销公司,wordpress get_category_parents简介
Qt的模型/视图#xff08;Model/View#xff09;架构是一种用于分离数据处理和用户界面展示的设计模式。它允许开发者将数据存储和管理#xff08;模型#xff09;与数据的显示和交互#xff08;视图#xff09;解耦#xff0c;从而提高代码的可维护性和可扩展性。…简介
Qt的模型/视图Model/View架构是一种用于分离数据处理和用户界面展示的设计模式。它允许开发者将数据存储和管理模型与数据的显示和交互视图解耦从而提高代码的可维护性和可扩展性。
Model/View的基本结构如下图所示 各部分功能如下所示
数据(Data):表示实际的数据模型(Model):与实际数据连接并为视图组件提供数据接口。从原始数据中提取所需内容用于视图进行显示和编辑。视图(View):从模型中获取每个数据项的模型索引通过模型索引获取数据然后为界面组件提供显示数据。
在Qt的模型/视图架构中 数据模型和显示界面分离允许同一数据模型在多个视图中展示且可在不修改模型的情况下自定义视图。 代理功能允许用户自定义数据的显示和编辑方式。在标准视图中代理通过模型索引与数据模型通信并提供编辑器如QLineEdit。 模型、视图和代理通过信号和槽进行通信 数据模型变化时通知视图更新。 视图操作时通知模型和代理。 编辑数据时代理通知模型和视图编辑器状态。
数据模型
所有基于项数据的模型都继承自QAbstractItemModel类该类定义了视图和代理访问数据的接口。数据模型中无需直接存储数据数据可以来自其他类、文件、数据库或其他任何数据源。
抽象类不能直接使用需要子类继承并实现一些虚函数。Qt中包含了用于项数据处理的模型类如下表
Model 类用途QStringListModel用于处理字符串列表数据的数据模型类QStandardltemModel标准的基于项数据的数据模型类每个项数据可以是任何数据类型QFileSystemModel计算机上文件系统的数据模型类QSortFilterProxyModel与其他数据模型结合提供排序和过滤功能的数据模型类QSqlQueryModel用于数据库SQL查询结果的数据模型类QSqlTableModel用于数据库的一个数据表的数据模型类QSqlRelationalTableModel用于关系型数据表的数据模型类
如果现有的这些模型类无法满足需求可以从 QAbstractltemModel、QAbstractListModel 或 QAbstractTableModel 继承生成自己的数据模型类。
视图组件
视图组件View就是显示数据模型的数据的界面组件。
Qt中提供的视图组件如下表
QListView用于显示单列的列表数据适用于一维数据的操作QTreeView用于显示树状结构数据适用于树状结构数据的操作QTableView用于显示表格状数据适用于二维表格型数据的操作QColumnView用多个QListView显示树状层次结构树状结构的一层用一个QListView显示QHeaderView提供行表头或列表头的视图组件如QTableView的行表头和列表头
代理(Delegate)
在Qt中代理Delegate用于在视图组件中编辑数据负责从模型获取数据并显示在编辑器中编辑完成后将数据保存回模型。默认情况下Qt使用QStyledItemDelegate作为代理它基于QAbstractItemDelegate抽象基类。对于特殊数据编辑需求如整数输入使用QSpinBox选择数据使用QComboBox可以通过继承QStyledItemDelegate创建自定义代理。
Model/View结构 如上图在Qt的模型/视图架构中所有数据模型类都继承自QAbstractItemModel并以表格的层次结构表示数据为视图组件和代理提供统一的数据存取接口。无论底层数据结构如何组织数据模型的表现形式可以是列表、表格或树状结构。数据模型的基本单元是项item每个项由行号、列号和父项定义其位置。在列表和表格中所有项共享一个顶层项实际顶层项并不存在而在树状结构中行号、列号和父项的关系更复杂但足以唯一确定一个项的位置并存取其数据。
模型索引
为了隔离数据表示和存取方式Qt引入了模型索引QModelIndex的概念。每个数据项通过模型索引进行存取视图组件和代理通过模型索引与数据模型交互。模型索引是一个临时指针用于提取或修改数据。由于数据模型的内部结构可能变化模型索引是临时的。如果需要持久化的模型索引则使用QPersistentModelIndex。
获取索引
数据模型的基本形式是表格数据但底层数据不一定以二维数组存储。行号和列号仅是为了方便组件间交互的约定。通过模型索引QModelIndex的行号、列号和父项索引可以存取数据。 列表和表格模型顶层节点用QModelIndex()表示所有数据项的父项是顶层项。 // 顶层节点总是用 QModelIndex() 表示 QModelIndex index1 model-index(0, 0, QModelIndex()); QModelIndex index2 model-index(1, 1, QModelIndex()); 树状结构模型节点可以有父节点构造模型索引时需指定行号、列号和父节点索引。例如节点B的父节点是节点A则其索引通过model-index(row, column, parentIndex)生成。 // 节点1 3的父节点是顶层节点节点2的父节点是节点1 QModelIndex index1 model-index(0, 0, QModelIndex()); QModelIndex index3 model-index(2, 1, QModelIndex()); QModelIndex index2 model-index(1,0,index1); 项的角色
在Qt的数据模型中每个项可以设置不同角色role的数据用于满足不同的显示或交互需求。QStandardItemModel中的QStandardItem通过setData(const QVariant value, int role)方法设置数据其中role指定数据的角色默认为Qt::UserRole 1。常见的角色包括 Qt::DisplayRole用于视图组件中显示的字符串。 Qt::ToolTipRole用于鼠标悬停时的提示信息。 Qt::DecorationRole用于装饰显示如图标。 Qt::UserRole用于自定义数据。
获取项的数据时也需要通过role指定获取哪种角色的数据例如data(int role)。视图组件和代理会根据角色来解释和显示数据不同组件对角色数据的处理方式可能不同某些角色的数据也可能被忽略。
模型视图的基本使用
创建视图
视图就是一个窗口所以使用模型/视图框架时无需使用QWidget,可以直接调用视图内置显示函数用于显示 // 创建视图 QListView view; // 把模型交给视图显示 view.setModel(model); view.show(); 创建模型 // 创建模型 auto model new QStandardItemModel(a); 添加项 // 给模型添加数据项 model-appendRow(new QStandardItem(肖战)); model-insertRow(0,new QStandardItem(蔡徐坤)); 添加子项
给模型中的QStandardItem添加子项只对QTreeView起作用 QStandardItem* item new QStandardItem(蔡徐坤); auto* subItem new QStandardItem(个人信息); subItem-appendRow(new QStandardItem(18岁)); subItem-appendRow(new QStandardItem(身高190cm)); item-appendRow(subItem); item-appendRow(new QStandardItem(生活习惯)); model-appendRow(item); 修改项 // 修改数据项 model-setItem(1,new QStandardItem(陈立农)); model-setData(index,大碗宽面,Qt::ItemDataRole::DisplayRole); //也可用于修改数据项 删除项 // 删除数据项从模型中移除并释放内存 //model-removeRow(0); //model-removeRows(0,2); // 指定起始行和行数 // 删除数据项但不释放内存 auto itemLists model-takeRow(1); qDebug()itemLists.size(); for(auto item:itemLists) { // 需要手动释放内存 delete item; } qDebug()model-rowCount() model-columnCount(); 获取项的索引 // item索引 auto item new QStandardItem(wyf); model-appendRow(item); QModelIndex index model-indexFromItem(item); qDebug()index; 查找项 // 查询数据项 auto res model-findItems(蔡徐坤); if(res.isEmpty()) qDebug()未找到该数据!; for(auto r:res) { qDebug()找到数据r-data(Qt::ItemDataRole::DisplayRole).toString(); } 设置角色数据 // 角色ItemDataRole model-setData(index,大碗宽面,Qt::ItemDataRole::DisplayRole); //也可用于修改数据项 item-setData(QColor(0,0,0),Qt::ItemDataRole::DecorationRole); //设置装饰角色 item-setData(我是帅哥,Qt::ItemDataRole::UserRole); //设置用户角色 qDebug()item-data(Qt::UserRole).toString(); //获取用户角色信息 视图信号连接槽 // 连接信号与槽 QObject::connect(view,QListView::clicked,[](const QModelIndex idx){ qDebug()idx.data(Qt::DisplayRole).toString(); }); 综合代码
#include QStandardItemModel
#include QListView
#include QApplicationint main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建模型auto model new QStandardItemModel(a);// 创建视图QListView view;// 把模型交给视图显示view.setModel(model);view.show();// 给模型添加数据项model-appendRow(new QStandardItem(肖战));model-insertRow(0,new QStandardItem(蔡徐坤));// 修改数据项model-setItem(1,new QStandardItem(陈立农));// 删除数据项从模型中移除并释放内存//model-removeRow(0);//model-removeRows(0,2); // 指定起始行和行数// 删除数据项但不释放内存auto itemLists model-takeRow(1);qDebug()itemLists.size();for(auto item:itemLists){// 需要手动释放内存delete item;}qDebug()model-rowCount() model-columnCount();// item索引auto item new QStandardItem(wyf);model-appendRow(item);QModelIndex index model-indexFromItem(item);qDebug()index;// 角色ItemDataRolemodel-setData(index,大碗宽面,Qt::ItemDataRole::DisplayRole); //也可用于修改数据项item-setData(QColor(0,0,0),Qt::ItemDataRole::DecorationRole); //设置装饰角色item-setData(我是帅哥,Qt::ItemDataRole::UserRole); //设置用户角色qDebug()item-data(Qt::UserRole).toString(); //获取用户角色信息// 查询数据项auto res model-findItems(蔡徐坤);if(res.isEmpty())qDebug()未找到该数据!;for(auto r:res){qDebug()找到数据r-data(Qt::ItemDataRole::DisplayRole).toString();}// 设置是否可选item-setCheckable(true);// 连接信号与槽QObject::connect(view,QListView::clicked,[](const QModelIndex idx){qDebug()idx.data(Qt::DisplayRole).toString();});// 添加子项,只对QTreeView视图起作用// auto subItem new QStandardItem(个人信息);// subItem-appendRow(new QStandardItem(18岁));// subItem-appendRow(new QStandardItem(身高180cm));// model-item(0)-appendRow(subItem);return a.exec();
}