By Xchen 20160627
截图:
创建过程:
1. 声明一个QDirModel对象model;
2. 分别声明三个视图对象QTreeView、QTableView、QListView;
3. 设置视图对象的模型为setModel(model);
4. 设置视图的选择模式setSelectionMode(QAbstractItemView::MultiSelection);
5. 信号槽的连接
6. 分隔窗体的设置
头文件:
#include <QApplication>
#include <QAbstractItemModel>
#include <QAbstractItemView>
#include <QItemSelectionModel>
#include <QDirModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QSplitter>
QItemSelectionModel类:用来设置模型的选择模式的。
By Xchen 20160628
所有的模型都基于QAbstractItemModel类。这个类定义了一个使用视图和委托来访问数据的接口。数据本身不是必须要存储在模型中,可以在一个数据结构或一个单独的类、文件、数据库、或其它一些应用组件。
QAbstractItemModel为数据提供了一个接口,它足够的灵活性来处理表格、列表、树形式的数据视图。然而,实现新的列表和类似于表的数据结构模型时,QAbstractListModel和QAbstractTableModel类是更好的起点,因为它们提供了适当的常用的功能的默认实现。这些类可以派生子类,用来提供支持特定种类的列表和表格的模型。
Qt提供了一些现成的模型,可以用来处理数据项:
在模型/视图结构中,模型提供了视图与委托访问数据的标准接口。在Qt中,标准的接口由QAbstractItemModel类定义。无论多么数据项被存储在任何底层的数据结构中,QAbstractItemModel的所有子类所代表的数据作为包含视图项的分层结构。视图使用这个约定来访问模型中的数据项,但并不限制将该信息传达给用户的方式。
为确保数据被分开被访问,模型索引的概念被引入。可以通过模型索引来获得每条信息。视图与委托使用这些索引来请求显示的数据项。因此,模型只需要知道如何获取数据,并通过模型管理的数据的类型可以被相当普遍定义。型号索引包含一个指向创建它们的模型的指针,在处理多个模型时可以防止混乱。
QAbstractItemModel *model = index.model();
模型索引提供临时参考信息,并且可以用于通过模型来检索或修改数据。由于模型可能重组其内部结构,模型的索引可能会变得无效,不宜存储。如果需要长期参考一条信息,必须创建一个持久性模型索引。这为模型保持最新信息提供了一个参考。临时模型索引由QModelIndex类提供,持久性模型索引由QPersistentModelIndex类提供。
取得对应于数据项的模型索引,模型中必须制定三个属性:一个行号、一个列号,以及父项的模型索引。
在最基本的形式中,模型可以被一个简单的表访问,表项位于行号和列号,这并不意味着底层数据存储在数据结构中,使用行号和列号只是一个惯例,以允许组件相互通信。我们可以通过指定行号和列号的模型索引有关的任何特定信息,通过下面的方式得到项目的索引:
QModelIndex index = model->index(row, column, …);
模型提供的接口简单,单级的数据结构如列表和表格不需要提供任何其他信息。但是,正如上面的代码所示,当获得一个模型索引时,我们需要提供更多的信息。
请注意,QStringListModel被声明为一个QAbstractItemModel。这使我们能够为模型使用抽象接口,并确保代码仍然有效,即使我们使用不同的模型替换了字符串列表模型。
由而QListView提供的列表视图足以展示字符串列表模型中的项目。我们构建视图,并设置模型可以使用下面代码:
QAbstractItemModel *model = new QStringListModel(numbers);
QListView *view = new QListView;
view->setModel(model);
视图正常显示方式
view->show();
return app.exec();
}
视图展现模型的内容,通过模型的接口访问数据。当用户试图编辑一个项目时,视图使用缺省代表提供一个编辑器部件。
提供了完整的实现为各种不同的视图:而QListView显示项目列表,QTableView中从一个表模型中显示数据,QTreeView则显示了层次列表的数据模型项目。每个类是基于QAbstractItemView抽象基类。虽然这些类是准备使用的实现,他们也可以被子类化,以提供自定义的视图。
QAbstractItemDelegate在模型/视图框架中代表抽象的基类。默认的委托实现由QStyledItemDelegate提供,这被Qt的标准视图用作默认的委托。然而,QStyledItemDelegate和QItemDelegate独立替代绘画,且为视图项提供编辑器。它们之间的区别在于QStyledItemDelegate使用当前样式来绘制项目。因此,建议实现自定义委托或当与Qt样式表一起使用时,使用QStyledItemDelegate作为基类。
在模型/视图结构中有两种接近的排序方式,选择哪种方式取决于你的基础模型。
如果你的模型是可排序的,也就是说,如果重新实现了QAbstractItemModel::sort()方法,QTableView和QTreeView都提供了一个API,允许以编程方式排序来排序模型数据。此外,可以启用交互式排序(即允许用户将数据通过单击视图的标题进行排序),由QHeaderView::sortIndicatorChanged()信号分别连接到QTableView:: sortByColumn()槽或QTreeView::sortByColumn()槽。
另一种方法,如果模型没有所需的接口,或者如果想使用一个列表视图来显示数据,使用代理模型呈现数据视图之前应转换模型的结构。
一些便利类都源于标准视图类的依赖Qt的项目为基础的项目视图和表类应用的好处。他们不打算被继承。
这些类的实例包括QListWidget,QTreeWidget和QTableWidget。
这些类比视图类灵活性差,且不能与任意的模型使用。建议使用模型/视图的方法来处理在项目视图中的数据,除非强烈需要一个基于项目的类。
如果想利用模型/视图提供的特性方法,同时使用一个基于项目的接口,可以考虑使用视图类,例如:QListView、QTableView、QTreeView与QStandardItemModel。
example01:
#include <QApplication>
#include <QSplitter>
#include <QFileSystemModel>
#include <QDir>
#include <QTreeView>
#include <QListView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSplitter *splitter = new QSplitter(Qt::Vertical,0);
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
QTreeView *tree = new QTreeView(splitter);
tree->setModel(model);
tree->setRootIndex(model->index(QDir::currentPath()));
QListView *list = new QListView(splitter);
list->setModel(model);
list->setRootIndex(model->index(QDir::currentPath()));
splitter->setWindowTitle("Two views onto the same file system model");
splitter->show();
return a.exec();
}
一个模型可以为多个视图所使用。在下面的代码中,我们创建两个表视图,使用的均是创建好的同一个模型。
QTableView *firstTableView = new QTableView;
QTableView *secondTableView = new QTableView;
firstTableView->setModel(model);
secondTableView->setModel(model);
在模型/视图框架中使用信号和槽是指更改模型可以传递给所有相连的视图,以确保始终可以访问相同的数据,而不管所使用的视图。
上面的图显示了统一模型的两种不同的视图,每个都包含了一些选定的项目。尽管模型中的数据在视图显示一致,每个视图维护它自己的内部选择模型。这在某些情况下有用,但对于许多应用来说,则需要一个共享的选择模型。
虽然视图类提供自己的默认选择模型很方便,但当我们使用多个视图到同一个模型时,通常需要所有的模型数据和用户的选择在所有视图显示一致。由于视图类允许其内部选择模型进行更换,那么可以使用如下方式实现视图之间的统一:
secondTableView->setSelectionModel(firstTableView->selectionModel());
第二个视图给出了第一个视图的选择模型。这两种视图现在在同一个选择模型进行操作,保持了数据和所选项目的同步。
原文:https://www.cnblogs.com/zhoug2020/p/14330781.html