Provides support for sorting and filtering data passed between another model and a view.
More...
|
| QSortFilterProxyModel (QObject *parent=nullptr) |
|
| ~QSortFilterProxyModel () |
|
QModelIndex | buddy (const QModelIndex &index) const override |
|
bool | canFetchMore (const QModelIndex &parent) const override |
|
int | columnCount (const QModelIndex &parent=QModelIndex ()) const override |
|
QVariant | data (const QModelIndex &index, int role=Qt::DisplayRole) const override |
|
bool | dropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override |
|
bool | dynamicSortFilter () const |
|
void | fetchMore (const QModelIndex &parent) override |
|
Qt::CaseSensitivity | filterCaseSensitivity () const |
|
int | filterKeyColumn () const |
|
QRegularExpression | filterRegExp () const |
|
int | filterRole () const |
|
Qt::ItemFlags | flags (const QModelIndex &index) const override |
|
bool | hasChildren (const QModelIndex &parent=QModelIndex ()) const override |
|
QVariant | headerData (int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override |
|
QModelIndex | index (int row, int column, const QModelIndex &parent=QModelIndex ()) const override |
|
bool | insertColumns (int column, int count, const QModelIndex &parent=QModelIndex ()) override |
|
bool | insertRows (int row, int count, const QModelIndex &parent=QModelIndex ()) override |
|
bool | isSortLocaleAware () const |
|
QModelIndex | mapFromSource (const QModelIndex &sourceIndex) const override |
|
QItemSelection | mapSelectionFromSource (const QItemSelection &sourceSelection) const override |
|
QItemSelection | mapSelectionToSource (const QItemSelection &proxySelection) const override |
|
QModelIndex | mapToSource (const QModelIndex &proxyIndex) const override |
|
QModelIndexList | match (const QModelIndex &start, int role, const QVariant &value, int hits=1, Qt::MatchFlags flags=Qt::MatchFlags (Qt::MatchStartsWith|Qt::MatchWrap)) const override |
|
QMimeData * | mimeData (const QModelIndexList &indexes) const override |
|
QStringList | mimeTypes () const override |
|
QObject * | parent () const |
|
QModelIndex | parent (const QModelIndex &child) const override |
|
bool | removeColumns (int column, int count, const QModelIndex &parent=QModelIndex ()) override |
|
bool | removeRows (int row, int count, const QModelIndex &parent=QModelIndex ()) override |
|
int | rowCount (const QModelIndex &parent=QModelIndex ()) const override |
|
bool | setData (const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override |
|
void | setDynamicSortFilter (bool enable) |
|
void | setFilterCaseSensitivity (Qt::CaseSensitivity cs) |
|
void | setFilterKeyColumn (int column) |
|
void | setFilterRegExp (const QRegularExpression ®Exp) |
|
void | setFilterRole (int role) |
|
bool | setHeaderData (int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::EditRole) override |
|
void | setSortCaseSensitivity (Qt::CaseSensitivity cs) |
|
void | setSortLocaleAware (bool on) |
|
void | setSortRole (int role) |
|
void | setSourceModel (QAbstractItemModel *sourceModel) override |
|
QModelIndex | sibling (int row, int column, const QModelIndex &idx) const override |
|
void | sort (int column, Qt::SortOrder order=Qt::AscendingOrder) override |
|
Qt::CaseSensitivity | sortCaseSensitivity () const |
|
int | sortColumn () const |
|
Qt::SortOrder | sortOrder () const |
|
int | sortRole () const |
|
QSize | span (const QModelIndex &index) const override |
|
Qt::DropActions | supportedDropActions () const override |
|
| QAbstractProxyModel (QObject *parent=nullptr) |
|
| ~QAbstractProxyModel () = default |
|
bool | canDropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override |
|
QMap< int, QVariant > | itemData (const QModelIndex &proxyIndex) const override |
|
void | revert () override |
|
bool | setItemData (const QModelIndex &index, const QMap< int, QVariant > &roles) override |
|
QAbstractItemModel * | sourceModel () const |
|
bool | submit () override |
|
Qt::DropActions | supportedDragActions () const override |
|
| QAbstractItemModel (QObject *parent=nullptr) |
|
virtual | ~QAbstractItemModel () |
|
bool | hasIndex (int row, int column, const QModelIndex &parent=QModelIndex ()) const |
|
bool | insertColumn (int column, const QModelIndex &parent=QModelIndex ()) |
|
bool | insertRow (int row, const QModelIndex &parent=QModelIndex ()) |
|
bool | moveColumn (const QModelIndex &sourceParent, int sourceColumn, const QModelIndex &destinationParent, int destinationChild) |
|
virtual bool | moveColumns (const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) |
|
bool | moveRow (const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild) |
|
virtual bool | moveRows (const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) |
|
QObject * | parent () const |
|
bool | removeColumn (int column, const QModelIndex &parent=QModelIndex ()) |
|
bool | removeRow (int row, const QModelIndex &parent=QModelIndex ()) |
|
virtual QMultiHash< int, QString > | roleNames () const |
|
| QObject (QObject *parent=nullptr) |
|
| ~QObject () |
|
bool | blockSignals (bool block) |
|
const QList< QObject * > & | children () const |
|
bool | connect (const QObject *sender, const QString &signalMethod, const QString &location, const QString &slotMethod, Qt::ConnectionType type=Qt::AutoConnection) |
|
bool | connect (const QObject *sender, const QString &signalMethod, const QString &slotMethod, Qt::ConnectionType type=Qt::AutoConnection) |
|
bool | disconnect (const QObject *receiver, const QString &slotMethod=QString ()) const |
|
bool | disconnect (const QString &signalMethod, const QString &location, const QObject *receiver=nullptr, const QString &slotMethod=QString ()) const |
|
bool | disconnect (const QString &signalMethod=QString (), const QObject *receiver=nullptr, const QString &slotMethod=QString ()) const |
|
void | dumpObjectInfo () |
|
void | dumpObjectTree () |
|
QList< QString > | dynamicPropertyNames () const |
|
virtual bool | event (QEvent *event) |
|
virtual bool | eventFilter (QObject *watched, QEvent *event) |
|
template<typename T > |
T | findChild (const QString &childName=QString ()) const |
|
template<class T > |
QList< T > | findChildren (const QRegularExpression ®Exp, Qt::FindChildOptions options=Qt::FindChildrenRecursively) const |
|
template<class T > |
QList< T > | findChildren (const QString &childName=QString (), Qt::FindChildOptions options=Qt::FindChildrenRecursively) const |
|
bool | inherits (const QString &className) const |
|
void | installEventFilter (QObject *filterObj) |
|
bool | isWidgetType () const |
|
bool | isWindowType () const |
|
void | killTimer (int id) |
|
const QMetaObject * | metaObject () const |
|
void | moveToThread (QThread *targetThread) |
|
QString | objectName () const |
|
QObject * | parent () const |
|
template<class T = QVariant> |
T | property (const QString &name) const |
|
void | removeEventFilter (QObject *obj) |
|
void | setObjectName (const QString &name) |
|
void | setParent (QObject *parent) |
|
bool | setProperty (const QString &name, const QVariant &value) |
|
bool | signalsBlocked () const |
|
int | startTimer (int interval, Qt::TimerType timerType=Qt::CoarseTimer) |
|
QThread * | thread () const |
|
|
void | sourceModelChanged () |
|
void | columnsAboutToBeInserted (const QModelIndex &parent, int first, int last) |
|
void | columnsAboutToBeMoved (const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) |
|
void | columnsAboutToBeRemoved (const QModelIndex &parent, int first, int last) |
|
void | columnsInserted (const QModelIndex &parent, int first, int last) |
|
void | columnsMoved (const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) |
|
void | columnsRemoved (const QModelIndex &parent, int first, int last) |
|
void | dataChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >()) |
|
void | headerDataChanged (Qt::Orientation orientation, int first, int last) |
|
void | layoutAboutToBeChanged (const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint) |
|
void | layoutChanged (const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint) |
|
void | modelAboutToBeReset () |
|
void | modelReset () |
|
void | rowsAboutToBeInserted (const QModelIndex &parent, int first, int last) |
|
void | rowsAboutToBeMoved (const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) |
|
void | rowsAboutToBeRemoved (const QModelIndex &parent, int first, int last) |
|
void | rowsInserted (const QModelIndex &parent, int first, int last) |
|
void | rowsMoved (const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) |
|
void | rowsRemoved (const QModelIndex &parent, int first, int last) |
|
void | destroyed (QObject *obj=nullptr) |
|
void | objectNameChanged (const QString &objectName) |
|
static bool | connect (const QObject *sender, const QMetaMethod &signalMethod, const QObject *receiver, const QMetaMethod &slotMethod, Qt::ConnectionType type=Qt::AutoConnection) |
|
static bool | connect (const QObject *sender, const QString &signalMethod, const QObject *receiver, const QString &slotMethod, Qt::ConnectionType type=Qt::AutoConnection, const QString &location=QString ()) |
|
static bool | connect (const QObject *sender, const QString &signalMethod, const QString &location, const QObject *receiver, const QString &slotMethod, Qt::ConnectionType type=Qt::AutoConnection) |
|
template<class Sender , class SignalClass , class... SignalArgs, class Receiver , class SlotClass , class... SlotArgs, class SlotReturn > |
static bool | connect (const Sender *sender, void (SignalClass::*signalMethod)(SignalArgs...), const Receiver *receiver, SlotReturn (SlotClass::*slotMethod)(SlotArgs...), Qt::ConnectionType type=Qt::AutoConnection) |
|
template<class Sender , class SignalClass , class... SignalArgs, class Receiver , class T > |
static bool | connect (const Sender *sender, void (SignalClass::*signalMethod)(SignalArgs...), const Receiver *receiver, T slotLambda, Qt::ConnectionType type=Qt::AutoConnection) |
|
static bool | disconnect (const QObject *sender, const QMetaMethod &signalMethod, const QObject *receiver, const QMetaMethod &slotMethod) |
|
static bool | disconnect (const QObject *sender, const QString &signalMethod, const QObject *receiver, const QString &slotMethod) |
|
static bool | disconnect (const QObject *sender, const QString &signalMethod, const QString &location, const QObject *receiver, const QString &slotMethod) |
|
static bool | disconnect (const QObject *sender, std::nullptr_t, const QObject *receiver, std::nullptr_t) |
|
template<class Sender , class SignalClass , class... SignalArgs, class Receiver , class SlotClass , class... SlotArgs, class SlotReturn > |
static bool | disconnect (const Sender *sender, void (SignalClass::*signalMethod)(SignalArgs...), const Receiver *receiver, SlotReturn (SlotClass::*slotMethod)(SlotArgs...)) |
|
template<class Sender , class SignalClass , class... SignalArgs, class Receiver > |
static bool | disconnect (const Sender *sender, void (SignalClass::*signalMethod)(SignalArgs...), const Receiver *receiver, std::nullptr_t slotMethod=nullptr) |
|
template<class Sender , class SignalClass , class... SignalArgs, class Receiver , class T > |
static bool | disconnect (const Sender *sender, void (SignalClass::*signalMethod)(SignalArgs...), const Receiver *receiver, T slotMethod) |
|
static QMetaObject & | staticMetaObject () |
|
static QString | tr (const char *text, const char *comment=nullptr, std::optional< int > numArg=std::optional< int >()) |
|
void | resetInternalData () |
|
void | resetInternalData () |
|
T | qobject_cast (QObject *object) |
|
| QObjectList |
|
The QSortFilterProxyModel class provides support for sorting and filtering data passed between another model and a view.
QSortFilterProxyModel can be used for sorting items, filtering out items, or both. The model transforms the structure of a source model by mapping the model indexes it supplies to new indexes, corresponding to different locations, for views to use. This approach allows a given source model to be restructured as far as views are concerned without requiring any transformations on the underlying data, and without duplicating the data in memory.
Assume we want to sort and filter the items provided by a custom model. The code to set up the model and the view, without sorting and filtering, would look like this:
MyItemModel *model = new MyItemModel(this);
To add sorting and filtering support to MyItemModel
, we need to create a QSortFilterProxyModel, call setSourceModel() with the MyItemModel
as argument, and install the QSortFilterProxyModel on the view:
At this point, neither sorting nor filtering is enabled; the original data is displayed in the view. Any changes made through the QSortFilterProxyModel are applied to the original model.
The QSortFilterProxyModel acts as a wrapper for the original model. If you need to convert source QModelIndexes to sorted/filtered model indexes or vice versa, use mapToSource(), mapFromSource(), mapSelectionToSource(), and mapSelectionFromSource().
- Note
- By default the model does not dynamically sort and filter data when the original model changes. This behavior can be changed by setting the dynamicSortFilter property.
Sorting
QTableView and QTreeView have a sortingEnabled property that controls whether the user can sort the view by clicking the view's horizontal header.
When this feature is on (the default is off), clicking on a header section sorts the items according to that column. By clicking repeatedly, the user can alternate between ascending and descending order.
The view calls the sort() method on the model to reorder data. You will need to either reimplement sort() in your model or use a QSortFilterProxyModel. The QSortFilterProxyModel class provides a generic sort() which uses the sortRole() of the items. It can handle several data types including int, QString, and QDateTime.
For hierarchical models, sorting is applied recursively to all child items. String comparisons are case sensitive by default. This can be changed by setting the sortCaseSensitivity property. Custom sorting behavior is achieved by subclassing QSortFilterProxyModel and reimplementing lessThan(), which is used to compare items.
{
if (leftData.
type() == QVariant::DateTime) {
} else {
if(left.column() == 1 && emailPattern->indexIn(leftString) != -1) {
leftString = emailPattern->cap(1);
}
if(right.column() == 1 && emailPattern->indexIn(rightString) != -1) {
rightString = emailPattern->cap(1);
}
return QString::localeAwareCompare(leftString, rightString) < 0;
}
}
An alternative approach to sorting is to disable sorting on the view and to impose a certain order to the user. This is done by explicitly calling sort() with the desired column and order as arguments on the QSortFilterProxyModel (or on the original model if it implements sort()).
proxyModel->
sort(2, Qt::AscendingOrder);
QSortFilterProxyModel can be sorted by column -1, in which case it returns to the sort order of the underlying source model.
Filtering
In addition to sorting, QSortFilterProxyModel can be used to hide items that do not match a certain filter. The filter is specified using a QRegularExpression object and is applied to the filterRole() (Qt::DisplayRole by default) of each item, for a given column. The QRegularExpression object can be used to match a regular expression or a wildcard pattern.
For hierarchical models the filter is applied recursively to all children. If a parent item does not match the filter, none of its children will be shown.
A common use case is to let the user specify the filter regular expression or wildcard pattern in a QLineEdit and to connect the textChanged() signal to setFilterRegExp() or setFilterWildcard() to reapply the filter.
Custom filtering behavior can be achieved by reimplementing the filterAcceptsRow() and filterAcceptsColumn() functions. For example, the following implementation ignores the filterKeyColumn property and performs filtering on columns 0, 1, and 2:
bool MySortFilterProxyModel::filterAcceptsRow(
int sourceRow,
const QModelIndex &sourceParent)
const {
}
If you are working with large amounts of filtering and have to invoke invalidateFilter() repeatedly, using reset() may be more efficient, depending on the implementation of your model. However, reset() returns the proxy model to its original state, losing selection information, and will cause the proxy model to be repopulated.
Subclassing
Many of the default implementations of methods in this class are written so that they call the equivalent methods in the source model. This simple proxying mechanism may need to be overridden for source models with more complex behavior. For example, if the source model provides a custom hasChildren() implementation, you should also provide one in the proxy model.
- See also
- QAbstractProxyModel, QAbstractItemModel, QIdentityProxyModel, Model/View Architecture, Custom Models