QSortFilterProxyModel(排序、过滤、代理model)(翻译)

简介(翻自帮助文档):

QSortFilterProxyModel类为另一个model及model的视图之间传递的数据,提供排序和过滤功能。

QSortFilterProxyModel可以用于对数据进行排序或过滤或both,它通过将原始model中的索引映射到对应数据的新位置的索引,来完成从原始model到视图之间的数据传递。如果视图中需要原始数据进行某种转换(排序or过滤),QSortFilterProxyModel可以对给定model中的数据进行重构,这种重构不涉及数据在内存中的复制。

1.正常model、view使用:


QTreeView *treeView = new QTreeView;
MyItemModel *model = new MyItemModel(this);

treeView->setModel(model);

2.代理model工作流程:



QTreeView *treeView = new QTreeView;                        
MyItemModel *sourceModel = new MyItemModel(this);

QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);    //1.创建QSortFilterProxyModel对象 
proxyModel->setSourceModel(sourceModel);    //2.设置源数据model
treeView->setModel(proxyModel);             //3.install the QSortFilterProxyModel on the view

3.初始化状态:

初始状态下,排序和过滤功能都是不可用的;你不会感觉到QSortFilterProxyModel的存在;

4.功能函数:

原始model和代理model之间存在index和selection的转换,函数如下:

原始model索引 mapToSource(代理model索引);
代理model索引 mapFromSource(原始model索引);
原始model的selection mapSelectionToSource(代理model的selection);
代理model的selection mapSelectionFromSource(原始model的selection);



5.关键属性:

dynamicSortFilter : bool



当原始model中的数据变化时,它决定代理model是否自动进行排序和过滤。

默认false。

note:值为true时不要更新原始model中的数据。

e.g:如果你给QComboBox设置了代理model,这时调用addItem()函数,进行数据更新。结果可能不是你想的那样。

另一种实现方法:dynamicSortFilter设为false,在更新了QComboBox数据后,手动调用sort()函数。

6.Sorting

QTableView and QTreeView,点击表头时,可以自动对该列数据进行排序(重复点击可在升序和降序间切换)。

开启方式:

treeView->setSortingEnabled(true);



默认false;

排序功能:

void QAbstractItemModel::sort ( int column, Qt::SortOrder order = Qt::AscendingOrder ) [virtual]



使数据可排序的两种方式:

  • 在原始model中实现sort()函数;
  • 使用QSortFilterProxyModel来包装你的model;

QSortFilterProxyModel默认提供的sort函数(对角色sortRole(默认为Qt::DisplayRole)进行操作),支持的数据类型:int、QString、QDataTime。

对于分层次model(tree),排序会在所有子item中递归进行。字符串比较时,默认对大小写敏感

子类化QSortFilterProxyModel,并重新实现 lessThan()函数(用于比较大小),来实现排序功能。

QSortFilterProxyModel可以在sort函数中传入-1列,这时数据会按原始model中顺序排列。

7.Filtering

过滤器使用 QRegExp对象作为参数,并作用于角色 filterRole()(Qt::DisplayRole by default),QRegExp对象可被用来匹配:

  • 正则表达式;
  • 通配符;
  • 固定字符串;

对于层次model,过滤器会应用于所有ziitem,如果父item不符合过滤器,那它的所有子item都会隐藏。

自定义的过滤器行为,可以通过重新实现 filterAcceptsRow() 和 filterAcceptsColumn() 函数。

如果你大量使用过滤器,需要经常调用invalidateFilter()(使无效)函数,使用reset()函数会效率更高。但调用reset()会使代理model彻底初始化,之前的选择信息会消失。

8.Subclassing

子类化时,简单的代理机制可能要随着原始model一起变化。例如,原始model中重写了hasChildren()函数,在代理model中你也要提供一个同样的函数。

你可能感兴趣的:(QSortFilterProxyModel(排序、过滤、代理model)(翻译))