概述
模型:主要是管理数据的,模型提供接口给外部(界面等)来访问数据,使得外部不需要知道数据的存储方式,这就阻断了界面和数据的直接联系,使得数据的不同存储反思方式都能使用统一的接口来被外部调用(通过索引机制来找到想要的数据)。
委托:用来管理每一项数据的具体显示方式和用户输入数据的方式,而且可以渲染每一项数据的显示(例如柱形图、圆饼等),是模型和视图的间接桥梁,也就是数据和显示方式的桥梁,也是用户输入信息与模型、视图的桥梁。
视图:可以看作是用来装在模型和委托的容器,可以直接显示模型中装载的数据,也可以通过调用委托来显示模型中的数据。
//模型
QFileSystemModel model;
... //model设置
//委托
SpinBoxDelegate* delegate = new SpinBoxDelegate(this);
...//delegate设置
//树视图
QTreeView tree;
tree.setModel(&model);
tree.setItemDelegate(delegate);
tree.show();
//列表视图
QListView list;
list.setMode(&model);
list.setItemDelegate(delegate);
list.show();
模型
概念
包含有模型索引、行和列、父项、项角色
项角色:一个数据项中可以包含多种项角色,是一对多的关系,不同的项角色(Qt::ItemDataRole),数据的表现方式不一样(即数据类型不一样)
使用
QT提供的常用模型的使用
QStringListModel、QStandardItemModel、QFileSystemModel、QSqlQueryModel、QSqlTableModel、QSqlRelationTableModel等
//1、创建模型对象
QStandardItemModel model;
//2、获取模型的根项
QStandardItem* parentItem = model.invisibleRootItem();
//3、创建一个数据项,将其设置为新的父项或者将其设置为根项的子项
QStandardItem* item0 = new QStandardItem();
...//数据项的一些设置(可以为各种项角色装载并数据)
parentItem->appendRow(item0); //这是将其设置为根项的子项
parentItem = item0; //这是将其设置为新的父项
//4、再创建一个数据项,将其设置为item0的子项
QStandardItem* item1 = new QStandardItem();
...//item1的一些设置(可以为各种项角色装载并数据)
item0.appendRow(item1);
//5、将model放入View
QTreeView view;
view.setModel(&model);
view.show();
//model中数据项的的读取
QModelIndex indexA = model.index(0, 0, QModelIndex());
model.rowCount(indexA);//索引为indexA的数据项的子项数目
QModelIndex indexB = model.index(0, 0, indexA);
model.data(indexB, Qt::EditRole); //索引为indexB的数据项以Qt::EditRole项角色形态装载的数据,这里是以EditRole形态装载的数据
model.data(indexB, Qt::ToolTipRole);//这里是ToolTipRole,具体是什么内容,主要是看此前被装载了什么数据进入这个项角色里面
自定义模型的创建
QT自带的示例程序:Simple Tree Model Example
1、创建自定义模型类,继承自QAbstractListModel或者QAbstractTableModel或者QAbstractItemModel
2、重写虚函数
int rowCount(const QModelIdex& parent = QModelIndex()) const; //返回模型的行数
QVariant data(const QModelIndex& index, int role) const; //返回指定模型索引中指定的项角色的数据
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; //返回树视图和表格视图的标头的指定项角色的内容
bool setDate(const QModelIdex& index, const QVariant& value, int role = Qt::EditRole);//设置指定模型索引中指定的项角色的数据,设置完后需要发送dataChanged()信号,目的是为了能告知视图数据已改变
Qt::ItemFlags flags(const QModelIndex& index) const; //返回指定模型索引的数据可支持的功能,比如可编辑等,目的是为了能使委托检测到该项的属性,然后决定可不可编辑等
bool inserRows(int position, int rows, const QModelIndex &index = QModelIndex());//添加行
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());//删除行
3、将model设置到view中正常调用即可。
视图
常用视图:QListView、QTableView、QTreeView
处理项目数据的选择的类:QItemSelectionModel
//获取视图的项目选择模型
QItemSelectionModel* selectionModel = tableView->selectionModel();
//选择的项表示
QItemSelection selection(索引1,索引n);//表示选择了从索引1到索引n
//设置视图的项目选择模型的新选择
selectionModel->select(selection, QItemSelectionModel::Select);
//当前项目内容
selectionModel()->currentIndex().data();
委托
QT自带的示例程序:Star Delegate Example、Spin Box Delegate Example
创建自定义委托
1、创建自定义委托类,继承自QItemDelegate
2、重写函数
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;//为指定索引的数据项创建编辑器部件
void setEditorData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;//为指定索引的数据项的编辑器部件设置数据,即将数据显示到编辑器上
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;//为模型中的指定索引的数据项设置数据,即将将编辑器上输入的内容写入到model里
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const;//更新编辑器的几何布局
项目视图的便捷类
QListWidget、QTreeWidget、QTableWidget
使用简单,适用于少量数据的存储和显示,因为它们没有将视图和模型进行分离,所以没有视图类灵活,不能和任意的模型仪器使用。当然了,我们一般建议使用模型/视图的方式来处理数据。
在项目视图中使用QT的拖放操作
参考《霍亚飞编著**__** _Qt Creator快速入门第三版_.pdf 》的16.6章节
QT自带的示例程序:Drag and Drop Puzzle Example
为模型设置筛选器(代理模型)
参考《霍亚飞编著**__** _Qt Creator快速入门第三版_.pdf 》的16.7.1章节
QT自带的示例程序:Basic Sort/Filter Model Example、Address Book Example
QT自带的自定义代理模型示例程序:Custom Sort/Filter Model Example
数据-窗口映射器(即数据模型的某个区域可以关联到其他组件上,然后可以在其他组件上面修改它)
参考《霍亚飞编著**__** _Qt Creator快速入门第三版_.pdf 》的16.7.2章节
QT自带的示例程序:Simple Widget Mapper Example 和 Combo Widget Mapper Example