Qt利用QSortFilterProxyModel代理實現(xiàn)自定義排序與聯(lián)合過濾
1. QsortFilterProxyModel介紹
QsortFilterProxyModel類用來為model和view之間提供強(qiáng)大的排序和過濾支持。將模型排序或者過濾后在視圖上顯示,并且無需對模型中的數(shù)據(jù)進(jìn)行任何轉(zhuǎn)換,也無需對模型在中數(shù)據(jù)進(jìn)行修改。
比如: 對某列篩選帶有”xxx”的關(guān)鍵字出來.并支持多則表達(dá)式
使用代理的項視圖模型代碼如下:
QTreeView *treeView = new QTreeView; MyItemModel *sourceModel = new MyItemModel(this); QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(sourceModel); //將model放入代理中 treeView->setModel(proxyModel); //在視圖中安裝代理
2.QSortFilterProxyModel自定義排序
自定義排序需要子類化QsortFilterProxyModel,然后重寫lessThan().
注意 : 如果重寫了lessThan(),那么就不會再調(diào)用model的sort方法了.
lessThan()使用示例:
bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { //通過當(dāng)前視圖中的index位置獲取model中實際的數(shù)據(jù) QVariant leftData = sourceModel()->data(source_left); QVariant rightData = sourceModel()->data(source_right); switch ( source_left.column() ) { case 0 : //序號,需要判斷數(shù)字 case 3 : //信號ID,需要判斷數(shù)字 return leftData.toInt() < rightData.toInt(); break; default : //其它,只判斷字符串 return leftData.toString() < rightData.toString(); break; } return true; }
除了排序外,QSortFilterProxyModel還可以用來隱藏與某個過濾器不匹配的項。使用QRegExp對象指定篩選器,并將篩選器應(yīng)用于給定列的每個項的filterRole() (默認(rèn)情況下為Qt::DisplayRole)。QRegExp對象可用于匹配正則表達(dá)式、通配符模式或固定字符串。
3.過濾方法1-使用setFilterKeyColumn()過濾列
首先需要通過void QsortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)來設(shè)置FilterProxyModel的過濾器.
然后通過QsortFilterProxyModel::setFilterKeyColumn(int)來過濾某一列.
如果要更改大小寫匹配,可以通過QsortFilterProxyModel::sortCaseSensitivity()來設(shè)置.
示例代碼如下所示:
QTableView *view = new QTableView; MyItemModel *sourceModel = new MyItemModel(this); QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(sourceModel); //將model放入代理中 view->setModel(proxyModel); //在視圖中安裝代理 QRegExp regExp("^(-?\\d+)(\\.\\d+)?$", Qt::CaseSensitive, QRegExp::RegExp); //通過^(-?\d+)(\.\d+)?$來匹配整數(shù) proxyModel->setFilterRegExp(regExp); //安裝過濾器 proxyModel->setFilterKeyColumn(0); proxyModel->setFilterKeyColumn(2); //將第一列和第三列同時是整數(shù)的數(shù)據(jù)顯示出來.
每當(dāng)過濾格式改變,則setFilterRegExp()重新更新過濾器即可.
弊端:
但是這樣只能"與方式"顯示model,要第一列和第三列公共是整數(shù)的才能顯示出來,不能實現(xiàn)"或方式"顯示.
所以,如果要使用聯(lián)合多列過濾,建議使用過濾方法2來實現(xiàn).
4.過濾方法2-重寫filterAcceptsRow成員函數(shù)
以實現(xiàn)"只要第一列有整數(shù)或者第三列有整數(shù)的都顯示出來"為例,首先需要子類化QsortFilterProxyModel類,然后重寫filterAcceptsRow()或者filterAcceptsColumn()函數(shù).
由于我們篩選第一列和第三列,列號是明確的,而行號是未知的, 所以我們只重寫filterAcceptsRow()函數(shù).
示例代碼如下所示:
bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { //獲取model中實際的數(shù)據(jù) QString dataColumn1 = sourceModel()->index(source_row, 0, source_parent).data(Qt::DisplayRole).toString(); QString dataColumn3 = sourceModel()->index(source_row, 2, source_parent).data(Qt::DisplayRole).toString(); if(dataColumn1.contains(this->filterRegExp())) { return true; } else if(dataColumn3.contains(this->filterRegExp())) { return true; } return false; }
然后創(chuàng)建SortFilterProxyModel類時,只需要安裝過濾器即可:
SortFilterProxyModel *proxyModel = new SortFilterProxyModel(); proxyModel->setSourceModel(sourceModel); //將model放入代理中 treeView->setModel(proxyModel); //在視圖中安裝代理 proxyModel->setFilterRegExp("^(-?\\d+)(\\.\\d+)?$"); //安裝過濾器
每當(dāng)過濾格式改變,則setFilterRegExp()重新更新過濾器即可.
注意事項:
如果過濾方式改變了,比如從過濾第1列變成了過濾第2列,需要調(diào)用invalidateFilter()函數(shù),使之前的過濾失效,激活當(dāng)前過濾.
5.代碼示例
model采用上章代碼的CustomModel為例.支持篩選多列、篩選模式支持:或方式、與方式、
界面實現(xiàn)如下所示:
#ifndef SORTFILTERPROXYMODEL_H #define SORTFILTERPROXYMODEL_H #include <QObject> #include <QSortFilterProxyModel> #include <QList> class SortFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; bool m_isOr; QList<int> m_selectdList; public: explicit SortFilterProxyModel(QSortFilterProxyModel *parent = nullptr); void ChangeFilterMode(bool isOr); void ChangeFilterColumn( QList<int> selectdList); signals: }; #endif // SORTFILTERPROXYMODEL_H
sortfilterproxymodel.cpp如下所示:
#include "sortfilterproxymodel.h" #include <QDebug> SortFilterProxyModel::SortFilterProxyModel(QSortFilterProxyModel *parent) : QSortFilterProxyModel(parent) { } void SortFilterProxyModel::ChangeFilterMode(bool isOr) { m_isOr = isOr; invalidateFilter(); } void SortFilterProxyModel::ChangeFilterColumn( QList<int> selectdList) { m_selectdList = selectdList; invalidateFilter(); } bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { if(m_selectdList.isEmpty()) return true; foreach(int column, m_selectdList) { QString data = sourceModel()->index(source_row, column, source_parent).data(Qt::DisplayRole).toString(); bool mathd = this->filterRegularExpression().match(data).hasMatch(); if(m_isOr && mathd) { return true; } else if(!m_isOr && !mathd) { return false; } } if(m_isOr) return false; else return true; } bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { //通過當(dāng)前視圖中的index位置獲取model中實際的數(shù)據(jù) QVariant leftData = sourceModel()->data(source_left); QVariant rightData = sourceModel()->data(source_right); switch ( source_left.column() ) { case 0 : case 3 : return leftData.toInt() < rightData.toInt(); break; default : return leftData.toString() < rightData.toString(); break; } return true; }
到此這篇關(guān)于Qt利用QSortFilterProxyModel代理實現(xiàn)自定義排序與聯(lián)合過濾的文章就介紹到這了,更多相關(guān)Qt QSortFilterProxyModel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實現(xiàn)學(xué)生學(xué)籍管理系統(tǒng)課程設(shè)計
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生學(xué)籍管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07關(guān)于vector迭代器失效的幾種情況總結(jié)
下面小編就為大家?guī)硪黄P(guān)于vector迭代器失效的幾種情況總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12使用C# 判斷給定大數(shù)是否為質(zhì)數(shù)的詳解
本篇文章是對使用C#判斷給定大數(shù)是否為質(zhì)數(shù)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語言中對于循環(huán)結(jié)構(gòu)優(yōu)化的一些入門級方法簡介
這篇文章主要介紹了C語言中對于循環(huán)結(jié)構(gòu)優(yōu)化的一些入門級方法,包括算法設(shè)計的改進(jìn)來提高一些并行性等方法,要的朋友可以參考下2015-12-12