一、概述
Qt提供了一种略微不同于MVC(Model-View-Controller)的架构,称之为MVD(Model-View-Delgate)架构。即Controller实际上应由用户自己组合实现,Qt未提供专门的类来处理,Qt提供了一系列的Delegate协调Model和View,实现渲染、数据编辑和转换,不直接参与界面布局,而是与View配合进行细节控制以及将Model数据转换为View可用的格式。Qt 已经提供了一系列的Model、View、Delegate类以实现Model/View/Delegate架构。MVD架构可以实现数据和展示层的分离,使用MVD架构能够带来非常大的性能提升和开发的灵活性。
二、TreeModel
有一些数据体具有一定的层次结构,即含有子项,下面介绍这样的Model如何构建。
同时,在这个例子中将显示同一个Model在不同的View(QTreeView、QTableView、QListView)中的显示效果(不同的View中选择操作可以是联动的)。
下面是简要步骤:
1.创建一个标准模型
//创建标准数据模型
QStandardItemModel* standardModel = new QStandardItemModel(0,3);
//创建项目选择类,跟踪同一模型在不同View中的选择情况
QItemSelectionModel *selections = new QItemSelectionModel(standardModel);
2.构建TreeModel数据
TreeModel数据有父子等隶属关系,层次深度可能不一致,数据结构比较复杂,实际使用中,应根据数据来源(如文件)的具体情况专门编制针对性的处理方法。本例仅仅罗列了基础的函数,采用手动方式添加数据。
1)设置标题栏
standardModel->setHeaderData(0, Qt::Horizontal, "第一列");
2)获取根节点
QStandardItem *rootNode = standardModel->invisibleRootItem();
3)添加一级节点
QList<QStandardItem *> firstGroup =getRow(3,"教育类", "价格", "日期");
rootNode->appendRow(firstGroup);
节点可以是QList<QStandardItem *>,也可以是QStandardItem*,如:
QStandardItem *f111 = new QStandardItem("语文");
4)添加下级节点
对于QList<QStandardItem *>
firstGroup.first()->appendRow(f11);
对于QStandardItem *
QStandardItem *f111 = new QStandardItem("语文");
QStandardItem *f1111 = new QStandardItem("高一语文");
f111-> appendRow(f1111);
5)设置图标
item = standardModel->item(2,0);
item->setIcon(…);
全部代码如下:
#include <QApplication>
#include <QStandardItemModel>
#include <QSplitter>
#include <QTreeView>
#include <QTableView>
#include <QListView>
#include <QStyle>
QList<QStandardItem *> getRow(int count, ...);
void constructModel(QStandardItemModel* standardModel);
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(treemodel);
QApplication app(argc, argv);
QSplitter page;
QStandardItemModel* standardModel = new QStandardItemModel(0,3);
QItemSelectionModel *selections = new QItemSelectionModel(standardModel);
constructModel(standardModel);
//QTreeView------------------------------------------------------------------------
QTreeView *treeView = new QTreeView;
treeView->setModel(standardModel);
treeView->setSelectionModel(selections);
treeView->expandAll();
page.addWidget(treeView);
//QTableView------------------------------------------------------------------------
QTableView *table = new QTableView;
table->setModel(standardModel);
table->setSelectionModel(selections);
table->viewport()->setAttribute(Qt::WA_StaticContents);
page.addWidget(table);
//QListView--------------------------------------------------------------------------
QListView *list = new QListView;
list->setModel(standardModel);
list->setSelectionModel(selections);
list->setViewMode(QListView::IconMode);
list->setSelectionMode(QAbstractItemView::ExtendedSelection);
list->viewport()->setAttribute(Qt::WA_StaticContents);
page.addWidget(list);
page.show();
return app.exec();
}
void constructModel(QStandardItemModel* standardModel)
{
QStandardItem *item;
standardModel->setHeaderData(0, Qt::Horizontal, "第一列");
standardModel->setHeaderData(1, Qt::Horizontal, "第二列");
standardModel->setHeaderData(2, Qt::Horizontal, "第三列");
//root
QStandardItem *rootNode = standardModel->invisibleRootItem();
//1
QList<QStandardItem *> firstGroup =getRow(3,"教育类", "价格", "日期");
rootNode->appendRow(firstGroup);
item = standardModel->item(0,0);
item->setIcon(QApplication::style()->standardIcon(QStyle::StandardPixmap::SP_ComputerIcon));
//2
QList<QStandardItem *> secondGroup =getRow(3,"科技类", "型号", "厂商");
rootNode->appendRow(secondGroup);
item = standardModel->item(1,0);
item->setIcon(QApplication::style()->standardIcon(QStyle::StandardPixmap::SP_ComputerIcon));
//3
QList<QStandardItem *> thirdGroup =getRow(3,"体育类", "赛事", "奖牌数");
rootNode->appendRow(thirdGroup);
item = standardModel->item(2,0);
item->setIcon(QApplication::style()->standardIcon(QStyle::StandardPixmap::SP_ComputerIcon));
//1.1
QList<QStandardItem *> f11 =getRow(3,"高中", "", "2025-3-10");
firstGroup.first()->appendRow(f11);
//1.1.1
QStandardItem *f111 = new QStandardItem("语文");
f11.first()-> appendRow(f111);
//1.1.1.1
QStandardItem *f1111 = new QStandardItem("高一语文");
f111-> appendRow(f1111);
//1.2
QList<QStandardItem *> f12 =getRow(3,"初中", "25.0", "2025-2-10");
firstGroup.first()->appendRow(f12);
//2.1
QList<QStandardItem *> f21 =getRow(3,"手机", "Honor", "荣耀");
secondGroup.first()->appendRow(f21);
//2.2
QList<QStandardItem *> f22 =getRow(3,"电脑", "SKY102", "国产");
secondGroup.first()->appendRow(f22);
}
QList<QStandardItem *> getRow(int count, ...)
{
QList<QStandardItem *> rowItems;
va_list args;
va_start(args,count);
for(int i=0; i<count; i++){
const QString item = va_arg(args, char*);
rowItems << new QStandardItem(item);
}
va_end(args);
return rowItems;
}
https://download.youkuaiyun.com/download/cnbizz/90466827?spm=1001.2014.3001.5503
下一节介绍其它特殊类型的Model。