QtModelView学习笔记Word格式文档下载.docx

上传人:b****6 文档编号:21365686 上传时间:2023-01-30 格式:DOCX 页数:22 大小:390.63KB
下载 相关 举报
QtModelView学习笔记Word格式文档下载.docx_第1页
第1页 / 共22页
QtModelView学习笔记Word格式文档下载.docx_第2页
第2页 / 共22页
QtModelView学习笔记Word格式文档下载.docx_第3页
第3页 / 共22页
QtModelView学习笔记Word格式文档下载.docx_第4页
第4页 / 共22页
QtModelView学习笔记Word格式文档下载.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

QtModelView学习笔记Word格式文档下载.docx

《QtModelView学习笔记Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《QtModelView学习笔记Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。

QtModelView学习笔记Word格式文档下载.docx

models,views,delegates之间通过信号,槽机制来进行通讯:

从model发出的信号通知view数据源中的数据发生了改变。

从view发出的信号提供了有关被显示的数据项与用户交互的信息。

从delegate发生的信号被用于在编辑时通知model和view关于当前编辑器的状态信息。

Models

所有的itemmodels都基于QAbstractItemModel类,这个类定义了用于views和delegates访问数据的接口。

数据本身不必存储在model,数据可被置于一个数据结构或另外的类,文件,数据库,或别的程序组件中。

关于model的基本概念在ModelClasses部分中描述。

QAbstractItemModel提供给数据一个接口,它非常灵活,基本满足views的需要,无论数据用以下任何样的形式

表现,如tables,lists,trees。

然而,当你重新实现一个model时,如果它基于table或list形式的数据结构,最好从QAbstractListModel,QAbstractTableModel开始做起,因为它们提供了适当的常规功能的缺省实现。

这些类可以被子类化以支持特殊的定制需求。

子类化model的过程在CreateNewModel部分讨论

QT提供了一些现成的models用于处理数据项:

QStringListModel用于存储简单的QString列表。

QStandardItemModel管理复杂的树型结构数据项,每项都可以包含任意数据。

QDirModel 

提供本地文件系统中的文件与目录信息。

QSqlQueryModel,QSqlTableModel,QSqlRelationTableModel用来访问数据库。

假如这些标准Model不满足你的需要,你应该子类化QAbstractItemModel,QAbstractListModel或是

QAbstractTableModel来定制。

Views

不同的view都完整实现了各自的功能:

QListView把数据显示为一个列表,QTableView把Model中的数据以table的形式表现,QTreeView用具有层次结构的列表来显示model中的数据。

这些类都基于QAbstractItemView抽象基类,尽管这些类都是现成的,完整的进行了实现,但它们都可以用于子类化以便满足定制需求。

Delegates

QAbstractItemDelegate是model/view架构中的用于delegate的抽象基类。

缺省的delegate实现在QItemDelegate类中提供。

它可以用于Qt标准views的缺省delegate.

排序

在model/view架构中,有两种方法进行排序,选择哪种方法依赖于你的底层Model。

假如你的model是可排序的,也就是它重新实现了QAbstractItemModel:

:

sort()函数,QTableView与QTreeView都提供了API,允许你以编程的方式对Model数据进行排序。

另外,你也可以进行交互方式下的排序(例如,允许用户通过点击view表头的方式对数据进行排序),可以这样做:

把QHeaderView:

sectionClicked()信号与QTableView:

sortByColum()槽或QTreeView:

sortByColumn()槽进行联结就好了。

另一种方法是,假如你的model没有提供需要的接口或是你想用listview表示数据,可以用一个代理

model在用view表示数据之前对你的model数据结构进行转换。

便利类

许多便利类都源于标准的view类,它们方便了那些使用Qt中基于项的view与table类,它们不应该被子类化,

它们只是为Qt3的等价类提供一个熟悉的接口。

这些类有QListWidget,QTreeWidget,QTableWidget,它们提供了如Qt3中的QListBox,QlistView,QTable相似的行为。

这些类比View类缺少灵活性,不能用于任意的models,推介使用model/view的方法处理数据。

介绍

Qt提供了两个标准的models:

QStandardItemModel和QDirModel。

QStandardItemModel是一个多用途的model,可用于表示list,table,treeviews所需要的各种不同的数据结构。

这个model也持有数据。

QDirModel维护相关的目录内容的信息,它本身不持有数据,仅是对本地文件系统中的文件与目录的描述。

QDirModel是一个现成的model,很容易进行配置以用于现存的数据,使用这个model,可以很好地展示如何给一个现成的view设定model,研究如何用modelindexes来操纵数据。

model与views的搭配使用

QListView与QTreeView很适合与QDirModel搭配。

下面的例子在treeview与listview显示了相同的信息,QDirModel提供了目录内容数据。

这两个Views共享用户选择,因此每个被选择的项在每个view中都会被高亮。

先装配出一个QDirModel以供使用,再创建views去显示目录的内容。

这给我展示了使用model的最简单的方式。

model的创建与使用都在main()函数中完成:

 

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

QSplitter*splitter=newQSplitter;

QDirModel*model=newQDirModel;

//从缺省目录创建数据

QTreeView*tree=newQTreeView(splitter);

tree->

setModel(model);

setRootIndex(model->

index(QDir:

currentPath()));

QListView*list=newQListView(splitter);

list->

//配置一个view去显示model中的数据,只需要简单地调用setModel(),并把目录model作为参数传递

//setRootIndex()告诉views显示哪个目录的信息,这需要提供一个modelindex,然后用这个

//modelindex去model中去获取数据

//index()这个函数是QDirModel特有的,通过把一个目录做为参数,得到了需要的modelindex

//其他的代码只是窗口show出来,进入程序的事件循环就好了

splitter->

setWindowTitle("

Twoviewsontothesamedirectorymodel"

);

splitter->

show();

returnapp.exec();

}

上面的例子并没有展示如何处理数据项的选择,这包括很多细节,以后会提到。

Model类

基本概念

在model/view构架中,model为view和delegates使用数据提供了标准接口。

在Qt中,标准接口QAbstractItemModel类中被定义。

不管数据在底层以何种数据结构存储,QAabstractItemModel的子类会以层次结构的形式来表示数据,结构中包含了数据项表。

我们按这种约定来访问model中的数据项,但这个约定不会对如何显示这些数据有任何限制。

数据发生改变时,model通过信号槽机制来通知关联的views。

ModelIndexes

为了使数据存储与数据访问分开,引入了modelindex的概念。

通过modelindex,可以引用model中的数据项,Views和delegates都使用indexes来访问数据项,然后再显示出来。

因此,只有model需要了解如何获取数据,被model管理的数据类型可以非常广泛地被定义。

Modelindexes包含一个指向创建它们的model的指针,这会在配合多个model工作时避免混乱。

QAbstractItemModel*model=index.model();

modelindexes提供了对一项数据信息的临时引用,通过它可以访问或是修改model中的数据。

既然model有时会重新组织内部的数据结构,这时modelindexes便会失效,因此不应该保存临时的modelindexes。

假如需要一个对数据信息的长期的引用,那么应该创建一个persistentmodelindex。

这个引用会保持更新。

临时的modelindexes由QModelIndex提供,而具有持久能力的modelindexes则由QPersistentModelIndex提供。

在获取对应一个数据项的modelindex时,需要考虑有关于model的三个属性:

行数,列数,父项的modelindex。

行与列

在最基本的形式中,一个model可作为一个简单的表来访问,每个数据项由行,列数来定位。

这必不意味着

底层的数据用数组结构来存储。

行和列的使用仅仅是一种约定,它允许组件之间相互通讯。

可以通过指定

model中的行列数来获取任一项数据,可以得到与数据项一一对应的那个index。

QModelIndexindex=model->

index(row,column,...);

Model为简单的,单级的数据结构如list与tables提供了接口,它们如上面代码所显示的那样,不再需要别的信息被提供。

当我们在获取一个modelindex时,我们需要提供另外的信息。

上图代表一个基本的tablemodel,它的每一项用一对行列数来定位。

通过行列数,可以获取代表一个数据项的modelindex.

QModelIndexindexA=model->

index(0,0,QModelIndex());

QModelIndexindexB=model->

index(1,1,QModelIndex());

QModelIndexindexC=model->

index(2,1,QModelIndex());

一个model的顶级项,由QModelIndex()取得,它们上式被用作父项。

父项

类似于表的接口在搭配使用table或listview时理想的,这种行列系统与view显示的方式是确切匹配的。

然则,像treeviews这种结构需要model提供更为灵活的接口来访问数据项。

每个数据项可能是别的项的

父项,上级的项可以获取下级项的列表。

当获取model中数据项的index时,我们必须指定关于数据项的父项的信息。

在model外部,引用一个数据

项的唯一方法就是通过modelindex,因此需要在求取modelindex时指定父项的信息。

index(row,column,parent);

上图中,A项和C项作为model中顶层的兄弟项:

A有许多孩子,它的一个孩子B用以下代码获取:

index(1,0,indexA);

项角色

model中的项可以作为各种角色来使用,这允许为不同的环境提供不同的数据。

举例来说,Qt:

DisplayRole被用于访问一个字符串,它作为文本会在view中显示。

典型地,每个数据项都可以为许多不同的角色提供数据,标准的角色在Qt:

ItemDataRole中定义。

我们可以通过指定modelindex与角色来获取我们需要的数据:

QVariantvalue=model->

data(index,role);

q

角色指出了从model中引用哪种类型的数据。

views可以用不同的形式显示角色,因此为每个角色提供正确

的信息是非常重要的。

通过为每个角色提供适当数据,model也为views和delegates提供了暗示,如何正确地

把这些数据项显给用户。

不同的views可以自由地解析或忽略这些数据信息,对于特殊的场合,也可以定义

一些附加的角色。

概念总结:

1,Modelindexes为views与delegages提供model中数据项定位的信息,它与底层的数据结构无关。

2,通过指定行,列数,父项的modelindex来引用数据项。

3,依照别的组件的要求,modelindexes被model构建。

4,使用index()时,如果指定了有效的父项的modelindex,那么返回得到的modelindex对应于父项的某个孩子。

5,使用index()时,如果指定了无效的父项的modelindex,那么返回得到的modelindex对应于顶层项的某个孩子。

6,角色对一个数据项包含的不同类型的数据给出了区分。

使用ModelIndexes

QDirModel*model=newQDirModel;

QModelIndexparentIndex=model->

currentPath());

intnumRows=model->

rowCount(parentIndex);

for(introw=0;

row<

numRows;

++row)

QModelIndexindex=model->

index(row,0,parentIndex);

tringtext=model->

data(index,Qt:

DisplayRole).toString();

//Displaythetextinawidget.

}

以上的例子说明了从model中获取数据的基本原则:

1,model的尺寸可以从rowCount()与columnCount()中得出。

这些函数通常都需要一个表示父项的modelindex。

2,modelindexes用来从model中访问数据项,数据项用行,列,父项modelindex定位。

3,为了访问model顶层项,可以使用QModelIndex()指定。

4,数据项为不同的角色提供不同的数据。

为了获取数据,除了modelindex之外,还要指定角色。

创建新的Models

model/view组件之间功能的分离,允许创建model利用现成的views。

这也可以使用标准的功能图形用户接口组件像QListView,QTableView和QTreeView来显示来自各种数据源的数据为。

QAbstractListModel类提供了非常灵活的接口,允许数据源以层次结构的形式来管理信息,也允许以某种

方式对数据进行插入、删除、修改和存储。

它也提供了对拖拽操作的支持。

QAbstractListModel与QAbstractTableModel为简单的非层次结构的数据提供了接口,对于比较简单的list和tablemodels来说,这是不错的一个开始点。

设计一个Model

当我们为存在的数据结构新建一个model时,首先要考虑的问题是应该选用哪种model来为这些数据提供接口。

假如数据结构可以用数据项的列表或表来表示,那么可以考虑子类化QAbstractListModel或QAbstractTableModel

既然这些类已经合理地对许多功能提供缺省实现。

然而,假如底层的数据结构只能表示成具有层次结构的树型结构,那么必须得子类化QAbstractItemModel。

无论底层的数据结构采取何种形式,在特定的model中实现标准的QAbstractItemModelAPI总是一个不错的主意,这使得可以使用更自然的方式对底层的数据结构进行访问。

这也使得用数据构建model更为容易,其他

的model/view组件也可以使用标准的API与之进行交互。

一个只读model示例

这个示例实现了一个简单的,非层次结构的,只读的数据model,它基于QStringistModel类。

它有一个QStringList作为它内部的数据源,只实现了一些必要的接口。

为了简单化,它子类化了QAbstractListModel,这个基类提供了合理的缺省行为,对外提供了比QAbstractItemModel更为简单的接口。

当我们实现一个model时,不要忘了QAbstractItemModel本身不存储任何数据,它仅仅提供了给views访问

数据的接口。

classStringListModel:

publicQAbstractListModel

Q_OBJECT

public:

StringListModel(constQStringList&

strings,QObject*parent=0)

:

QAbstractListModel(parent),stringList(strings){}

introwCount(constQModelIndex&

parent=QModelIndex())const;

QVariantdata(constQModelIndex&

index,introle)const;

QVariantheaderData(intsection,Qt:

Orientationorientation,

introle=Qt:

DisplayRole)const;

private:

QStringListstringList;

};

除了构造函数,我们仅需要实现两个函数:

rowCount()返回model中的行数,data()返回与特定modelindex对应的数据项。

具有良好行为的model也会实现headerData(),它返回tree和tableviews需要的,在标题中显示的数据。

因为这是一个非层次结构的model,我们不必考虑父子关系。

假如model具有层次结构,我们也应该实现index()与parent()函数。

Model的尺寸

我们认为model中的行数与stringlist中的string数目一致:

intStringListModel:

rowCount(constQModelIndex&

parent)const

returnstringList.count();

在缺省情况下,从QAbstractListModel派生的model只具有一列,因此不需要实现columnCount()。

Model标题与数据

QVariantStringListModel:

data(constQModelIndex&

index,introle)const

if(!

index.isValid())

returnQVariant();

if(index.row()>

=stringList.size())

if(role==Qt:

DisplayRole)

returnstringList.at(index.row());

else

headerData(intsection,Qt:

introle)const

if(role!

=Qt:

if(orientation==Qt:

Horizontal)

returnQString("

Column%1"

).arg(section);

R

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1