[译]QSortFilterProxyModel文档

Detailed Description

    QSortFilterProxyModel 供给了支撑了在其他模型(model)和视图(view)之间传递数据时停止排序(sorting)和过滤(filtering)。

    QSortFilterProxyModel 可以用于排序(sorting) items或者过滤(filtering out)items或者排序并且过滤items。它把一个model的source结构通过model的index结构map到他新供给的index里面,这种方法允许一个model重新组织,当和他相关联的view,不须要在数据上请求任何转换,也不须要复制内存中的数据。

    假设我们想要在一个自定义model(custom model)供给排序(sort)和过滤(filter )items。在没有供给排序(sorting)和过滤的(filtering)功能的情况下,建立模型(model)和视图(view)的代码类似如下:

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

treeView->setModel(model)

 为了对 MyItemModel 添加排序(sorting)和过滤(filtering)的支撑,我们须要创建一个QSortFilterProxyModel(对象),调用setSourceModel()函数并将 MyItemModel (对象),作为函数的参数,然后在视图(view)上安装(install) QSortFilterProxyModel(对象),

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

proxyModel->setSourceModel(sourceModel);
treeView->setModel(proxyModel);

当初,无论是排序(sorting )还是过滤(filtering)都还未启用,原始数据表当初视图(view)上。通过QSortFilterProxyModel做的任何修改都会作用在原始模型(model)中。

    QSortFilterProxyModel对于原始的模型(model)来讲就相当于一个包装工具。如果想把原始的QModelIndex转换成可排序(sorted)/过滤(filtered)的模型(model),或者反之亦然,使用 mapToSource(), mapFromSource(), mapSelectionToSource(), 和mapSelectionFromSource()这些方法。

    注意:默许情况下,不管原始的模型(origina model)何时改变,它会动态自动重新排序(re-sorts )和重新过滤(re-filters )数据。

    Basic Sort/Filter Model 和 Custom Sort/Filter Model 例子说明了如何使用QSortFilterProxyModel来执行基本的排序(sorting)和过滤filtering ()和如何实现自定义子类(subclass)行为。

    

Sorting

    QTableView and QTreeView have a sortingEnabled property that controls whether the user can sort the view by clicking the view's horizontal header. For example:

    QTableView 和 QTreeView 有一个sortingEnabled属性,控制着用户是不是可以通过点击视图(view)的水平标题栏(horizontal header)来排序。例如:

treeView->setSortingEnabled(true);

当这个性质(feature)打开时(默许是关闭(off)),点击表头(header section)就会对本列(columm)的item停止排序(sorts).通过重复点击表头(header),用户可以交替的看到升序(ascending)和降序(descending order)的排序。

    模型和排序

    在幕后(Behind the scene),视图(view)调用模型(model)中的虚函数sort()重新排序(reorder)模型(model)中的数据。为了是自己的数据可以排序(sortable),我们可以在自己的模型(model)实现sort()方法,或者使用QSortFilterProxyModel来包装(wrap)这个模型(model)——QSortFilterProxyModel 供给了一个通用sort()的重新实现,来操纵items的sortRole() (默许是Qt::DisplayRole)。QSortFilterProxyModel 的sort()函数可以操纵多种数据类型,包含:int、 QString 和QDateTime. 对于分层模型(hierarchical models),排序(sorting)是递归(recursively)地应用到所有子元素(child items)。在默许情况下,字符串比较是大小写敏感的(case sensitive);这个属性可以通过设置 sortCaseSensitivity 来改变。

    自定义排序的行为时通过子类化(subclassing) QSortFilterProxyModel 和重新实现 lessThan() 方法。lessThan()是用来比较items的大小。例如:

 1 bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
 2                                       const QModelIndex &right) const
 3 {
 4     QVariant leftData = sourceModel()->data(left);
 5     QVariant rightData = sourceModel()->data(right);
 6 
 7     if (leftData.type() == QVariant::DateTime) {
 8         return leftData.toDateTime() < rightData.toDateTime();
 9     } else {
10         QRegExp *emailPattern = new QRegExp("([\\w\\.]*@[\\w\\.]*)");
11 
12         QString leftString = leftData.toString();
13         if(left.column() == 1 && emailPattern->indexIn(leftString) != -1)
14             leftString = emailPattern->cap(1);
15 
16         QString rightString = rightData.toString();
17         if(right.column() == 1 && emailPattern->indexIn(rightString) != -1)
18             rightString = emailPattern->cap(1);
19 
20         return QString::localeAwareCompare(leftString, rightString) < 0;
21     }
22 }

(这个代码片段来自Custom Sort/Filter Model的例子)

    另一种排序(sorting)是禁用对视图(view)停止排序(sorting ),并强加给用户以特定的次序。这是在 QSortFilterProxyModel 通过显式调用(explicitly calling ) sort () 用所需的列(desired column )和次序作为参数  (或上的原始模型(original model )实现 sort())。例如:

proxyModel->sort(2, Qt::AscendingOrder);

QSortFilterProxyModel 可以按-1列(column -1)排序(sorted),在这种情况下它返回到底层的源模型的排序次序(the sort order of the underlying source model)。

    

Filtering

    除了排序(sorting),QSortFilterProxyModel 可以用于隐藏与特定过滤器(a certain filter)不匹配的items。对于给定的一列,指定的过滤器(filter)使用QRegExp对象并应用于filterRole()(默许情况下是Qt::DisplayRole)的每一个items。QRegExp 对象可以用于匹配正则表达式、 通配符模式或一个固定的字符串。例如:

proxyModel->setFilterRegExp(QRegExp(".png", Qt::CaseInsensitive,
                                            QRegExp::FixedString));
proxyModel->setFilterKeyColumn(1);

对于分层模型(hierarchical models),过滤器(filter)被递归地应用到所有的孩子(children).如果一个父项(parent item)不匹配过滤器,它的所有孩子(children)将被表现。

    平日的一个用法是让用户通过QLineEdit指定过滤器(filte)正则表达式,通配符,然后通过连接textChanged()信号到槽setFilterRegExp(), setFilterWildcard(), setFilterFixedString()来响应过滤器(filter)。

    自定义过滤(Custom filtering)行为可以通过重新实现 filterAcceptsRow() 和 filterAcceptsColumn() 函数。例如 (实例:Custom Sort/Filter Model),下面的实现将疏忽 filterKeyColumn 属性和执行过滤(performs filtering )列 0、 1 和 2 :

 1 bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
 2         const QModelIndex &sourceParent) const
 3 {
 4     QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
 5     QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
 6     QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent);
 7 
 8     return (sourceModel()->data(index0).toString().contains(filterRegExp())
 9             || sourceModel()->data(index1).toString().contains(filterRegExp()))
10             && dateInRange(sourceModel()->data(index2).toDate());
11 }

(这个代码片段来自Custom Sort/Filter Model的例子)

    如果正在使用大批的筛选,并有多次调用 invalidateFilter(),使用reset()可能更有效,具体取决于模型(model)的实现。但是,reset()返回代理模型(proxy model )其最初的状态(original state)。这个状态失去了选择的信息(selection information),并将致使代理服模型(proxy model )必须重新填充(repopulated)。

    

Subclassing

    因为 QAbstractProxyModel 和它的子类从 QAbstractItemModel 派生的很多关于创建子类畸形模式的雷同建议也适用于代理模式。此外,值得注意很多此类中的函数的默许实现,以便他们有关源模型中调用等效的功能( In addition, it is worth noting that many of the default implementations of functions in this class are written so that they call the equivalent functions in the relevant source model. )。这种简略的代理机制可能须要覆盖源模型(source models )实现更复杂的行为;例如,如果源模型(source model )供给了一个自定义(custom)的hasChildren() 实现,则应还供给一个代理模型(代理模型)中。

 

查看原文:http://wavelee.info/2013/05/26/qsortfilterproxymodel-class/

官方文档:http://qt-project.org/doc/qt-4.8/qsortfilterproxymodel.html

posted @ 2013-05-28 18:35  云端的思念  阅读(1964)  评论(0)    收藏  举报