鍍金池/ 教程/ C/ QSortFilterProxyModel
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類之關(guān)聯(lián)存儲容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對話框之 QInputDialog
Qt 容器類之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對話框之 QColorDialog
QPainter(續(xù))
國際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對象
QSortFilterProxyModel
國際化(上)
組件布局
自定義 Model 之三
事件過濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對話框之 QFileDialog
自定義 model 之二
深入了解信號槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個對話框(下)
Qt 學(xué)習(xí)之路(32): 一個簡易畫板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫
自定義事件
編寫跨平臺的程序
MainWindow
初探信號槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對話框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類之順序存儲容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個對話框(上)
一個簡易畫板的實(shí)現(xiàn)(QWidget)

QSortFilterProxyModel

Qt 為我們預(yù)定義了很多 model,前面已經(jīng)說過了 QStringListModel、QDirModel(也算是 Qt 推薦使用的 QFileSystemModel 吧,這個在上一章最后重新加上了一段話,沒有注意的朋友去看看哦)。今天我們要說的這個 QSortFilterProxyModel 并不能單獨(dú)使用,看它的名字就會知道,它只是一個“代理”,真正的數(shù)據(jù)需要另外的一個 model 提供,并且它是用來排序和過濾的。所謂過濾,也就是說按照你輸入的內(nèi)容進(jìn)行數(shù)據(jù)的篩選,很像 Excel 里面的過濾器。不過 Qt 提供的過濾功能是基于正則表達(dá)式的,因而功能強(qiáng)大。

我們從代碼開始看起:

sortview.h


#ifndef SORTVIEW_H 
#define SORTVIEW_H 

#include <QtGui> 

class SortView : public QWidget 
{ 
        Q_OBJECT 
public: 
        SortView(); 

private: 
        QListView *view; 
        QStringListModel *model; 
        QSortFilterProxyModel *modelProxy; 
        QComboBox *syntaxBox; 

private slots: 
        void filterChanged(QString text); 
}; 

#endif // SORTVIEW_H

sortview.cpp


#include "sortview.h" 

SortView::SortView() 
{ 
        model = new QStringListModel(QColor::colorNames(), this); 

        modelProxy = new QSortFilterProxyModel(this); 
        modelProxy->setSourceModel(model); 
        modelProxy->setFilterKeyColumn(0); 

        view = new QListView(this); 
        view->setModel(modelProxy); 

        QLineEdit *filterInput = new QLineEdit; 
        QLabel *filterLabel = new QLabel(tr("Filter")); 
        QHBoxLayout *filterLayout = new QHBoxLayout; 
        filterLayout->addWidget(filterLabel); 
        filterLayout->addWidget(filterInput); 

        syntaxBox = new QComboBox; 
        syntaxBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 
        syntaxBox->addItem(tr("Regular expression"), QRegExp::RegExp); 
        syntaxBox->addItem(tr("Wildcard"), QRegExp::Wildcard); 
        syntaxBox->addItem(tr("Fixed string"), QRegExp::FixedString); 
        QLabel *syntaxLabel = new QLabel(tr("Syntax")); 
        QHBoxLayout *syntaxLayout = new QHBoxLayout; 
        syntaxLayout->addWidget(syntaxLabel); 
        syntaxLayout->addWidget(syntaxBox); 

        QVBoxLayout *layout = new QVBoxLayout(this); 
        layout->addWidget(view); 
        layout->addLayout(filterLayout); 
        layout->addLayout(syntaxLayout); 

        connect(filterInput, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); 
} 

void SortView::filterChanged(QString text) 
{ 
        QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax( 
                        syntaxBox->itemData(syntaxBox->currentIndex()).toInt()); 
        QRegExp regExp(text, Qt::CaseInsensitive, syntax); 
        modelProxy->setFilterRegExp(regExp); 
}

至于 main()函數(shù)的內(nèi)容,由于和前面的代碼幾乎是一樣的,這里就不再貼出來了。我們使用的是QColor::colorNames()函數(shù)提供的數(shù)據(jù)。這個函數(shù)返回值是一個 QStringList 類型的變量,可以給出預(yù)定義的顏色的名字。我們使用一個 QStringListModel 包裝這個數(shù)據(jù),這和前面的內(nèi)容沒有什么區(qū)別。然后創(chuàng)建一個 QSortFilterProxyModel 對象,使用它的 setSourceModel()函數(shù)將前面定義的QStringListModel 傳進(jìn)去,也就是我們需要對這個 model 進(jìn)行代理。那么我們需要過濾哪一列呢?雖然 QStringListModel 只有一列,但是我們也需要使用 setFilterKeyColumn()函數(shù)設(shè)置一下,以便讓這個 proxy 知道要過濾的是第0列。最后重要的一點(diǎn)是,QListView 的 model 必須設(shè)置為QSortFilterProxyModel,否則是看不到效果的。

下面的 QLineEdit 提供過濾數(shù)據(jù)的輸入,這個沒什么好說的。后面的 QComboBox 列出了三項(xiàng):


syntaxBox->addItem(tr("Regular expression"), QRegExp::RegExp); 
syntaxBox->addItem(tr("Wildcard"), QRegExp::Wildcard); 
syntaxBox->addItem(tr("Fixed string"), QRegExp::FixedString);

這是正則表達(dá)式的類型。正則表達(dá)式有一套通用的語法,但是對于不同的環(huán)境,正則表達(dá)式的規(guī)則可能是不一樣的。第一個 QregExp::RegExp 提供了最一般的正則表達(dá)式語法,不過這個語法不支持貪婪限定符。這也是 Qt 默認(rèn)的規(guī)則。如果你需要使用貪婪限定符,需要使用 QRegExp::RegExp2,根據(jù)文檔描述,這個將會是 Qt5 的默認(rèn)規(guī)則。第二個是 Unix 下 shell 很常見的一種規(guī)則。第三個即固定表達(dá)式,也就是說基本上不使用正則表達(dá)式的。

我們使用 connect()函數(shù),將 QLineEdit 的 textChanged()信號同 slot 連接起來。其中我們的slot 函數(shù)如下所示:


void SortView::filterChanged(QString text) 
{ 
        QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax( 
                        syntaxBox->itemData(syntaxBox->currentIndex()).toInt()); 
        QRegExp regExp(text, Qt::CaseInsensitive, syntax); 
        modelProxy->setFilterRegExp(regExp); 
}

第一步,使用 QComboBox 的選擇值創(chuàng)建一個 QRegExp::PatternSyntax 對象,然后利用這個語法規(guī)則構(gòu)造一個正則表達(dá)式,注意我們在 QLineEdit 里面輸入的內(nèi)容是通過參數(shù)傳遞進(jìn)來的,然后設(shè)置proxy 的過濾器的表達(dá)式。好了,就這樣運(yùn)行一下看看效果吧!

http://wiki.jikexueyuan.com/project/learn-road-qt/images/74.png" alt="" />

本文出自 “豆子空間” 博客,請務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918

上一篇:自定義委托下一篇:事件接收與忽略