Qt Model

QAbstractItemModel

model负责具体的数据存储和读写,对于abstractModel来说,它们不存储数据,也不直接使用,而是子类化后通过重写的关键函数和自定义的数据结构来存储和读写数据

//子类化,继承此类的子类必须实现:
index、parent、rowCount、columnCount、data、setData、flags、headerData、setHeaderData
setData和setHeaderData必须显示触发dataChanged和headerDataChanged信号
//每个model都要提供一个创建index函数,这样在提供行列数时才能返回index
QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const
{
	//必须使用createIndex来创建index
    return createIndex(row, column);//无层级model仅使用行列即可
	//若有层级关系,
	
}
//返回给定的index的父项,index类调用的parent实际上调用的就是这个函数
QModelIndex HistoryModel::parent(const QModelIndex &child) const
{
    return QModelIndex();//无层级model,父节点均为空节点
}
//将model的行列暴露给需要的对象,可以是不变的,也可以是可变的
int HistoryModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const
{
    return 5;//不变时返回一个固定数即可
}
int HistoryModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const
{
    return 2;
}
//当向model提供了一个index时,model如何返回相应index的数据
QVariant HistoryModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const
{
    if (role == Qt::TextAlignmentRole)
        return int(Qt::AlignLeft | Qt::AlignVCenter); 
    else if (role == Qt::DisplayRole) 
        return QString("row=%1,col=%2").
				arg(index.row()).arg(index.column());//通过index获取相应item
    else
        return QVariant();//若role无效则返回空的variant
}
//若model行列可变,则还需要实现insert和remove
bool HistoryModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex())
{
	beginInsertRow(parent,row,count);//必须先调用此函数,表示从row行开始,插入count个新列
	//此函数会发出信号,view或delegate必须在插入数据前处理此信号
	...
	endInsertRow();//结束时也必须调用此函数
}


QAbstractListModel

QAbstractTableModel

QStandardItemModel

itemModel结构
Qt Model_第1张图片

以一个QStandardItem为基础单位,将它们有机组织起来,可以形成list、table和tree以供不同的view显示

一个item包含若干个(role,data)的pair来表示多个数据,其实就是内部有一个QVector,其中每个元素都是一个pair

每个item都可以看做有一张二维表,其内保存了它的所有子item,所以此类非常灵活,可以用于多种视图

itemModel内部其实也就是包含了一个item节点作为root,再通过root的二维表进行child的管理,model对item的操作可以看做都是root执行的

//standardItem用法
item->setData/data();//关键读写函数
item->child/parent();//
item->setChild();//设置单个item为child
item->append/insertRow/Column();//添加多个item为child,有行列之分
item->removeRow/Column();//直接移除行列,并delete
item->takeRow/Column();//移除行列,但返回行列而不delete
item->row/column();//返回item所在行/列

//作为list
QStandardItemModel listModel;
QStandardItem *rootItem = listModel.invisibleRootItem();//获取模型最底层的根节点
for (int row = 0; row < 4; ++row)
{
 	QStandardItem *item = new QStandardItem(QString("%0").arg(row));//构造函数内部也是调用的setData
 	rootItem->appendRow(item);//将一个item作为一行插入,实现了list的效果
} 
QListView listView;
listView.setModel(&listModel);//设置到view上
//作为table
QStandardItemModel tableModel(4, 4);
for (int row = 0; row < 4; ++row) 
{
   for (int column = 0; column < 4; ++column) 
	{
    	QStandardItem *item = new QStandardItem(
     	QString("%0,%1").arg(row).arg(column));
    	tableModel.setItem(row, column, item);
   	}
} 
QTableView tableView;
tableView.setModel(&tableModel);
//作为tree
QStandardItemModel treeModel;
QStandardItem *parentItem = treeModel.invisibleRootItem();
for (int i = 0; i < 4; ++i) {
 	QStandardItem *item = new QStandardItem(QString("%0").arg(i));
 	parentItem->appendRow(items);//可以是单个item也可以是多个item
 	parentItem = item;//以层次顺序来添加item(子节点)
}
QTreeView treeView;
treeView.setModel(&treeModel);
//model用法
对item的操作与item完全一致,其实就是通过rootItem来完成的
model->invisibleRootItem();//返回root
model->findItems();//根据给出的text和flag查找item
model->indexFromItem/itemFromIndex();//index和item的相互转换
model->item();//通过指定行列数获取item
model->setItem();setItem在指定位置没有item时就相当于add,有就相当于覆盖,若给出的行列不存在,则会自动创建
model->setRow/ColumnCount();//设置整个model的行列数
model->setHorizontal/VerticalHeaderItem/Label();//设置表头

信号槽

//model中某item的data变化时触发
void itemChanged(QStandardItem *item)

QFileSystemModel

提供可以访问本地文件系统的model,通过model操作本地文件及目录

model=new QFileSystemModel(this);//创建一个model对象
model->setRootPath("F:/QtProject");//设置model的根目录root,即这个model只包含root及其子目录下的内容
treeView->setModel(model);//为model设置一个view,即指定model在UI界面中显示的组件
//treeView是最适合文件系统的view,设置后view中就自动设置好了格式并显示

model->fileName/Icon/Info/Path();//根据index查询相应文件的相关信息
model->index();//根据给出的路径返回文件的index
model->mkdir();//在给出的index所对应的目录下新建一个目录
model->rmdir/remove();//删除index相应的目录/文件
model->setFilter();//设置model的过滤器

信号槽

//
void directoryLoaded(const QString &path)
//每当有文件重命名时触发
void fileRenamed(const QString &path, const QString &oldName, const QString &newName) 
//root更改时触发
void rootPathChanged(const QString &newPath)

你可能感兴趣的:(QT,qt)