使用代理model QSortFilterProxyModel进行item筛选和排序

Qt为我们预定义了很多model,前面已经说过了QStringListModel、QDirModel(也算是Qt推荐使用的QFileSystemModel吧,这个在上一章最后重新加上了一段话,没有注意的朋友去看看哦)。今天我们要说的这个QSortFilterProxyModel并不能单独使用,看它的名字就会知道,它只是一个“代理”,真正的数据需要另外的一个model提供,并且它是用来排序和过滤的。所谓过滤,也就是说按照你输入的内容进行数据的筛选,很像Excel里面的过滤器。不过Qt提供的过滤功能是基于正则表达式的,因而功能强大。
 
我们从代码开始看起:
 
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    stringlistModel=new QStringListModel(QColor::colorNames(),this);
    //colorNames是静态函数,把Qt所知道的颜色作为QStringList返回,然后stringlistmodel作为这个返回的QStringList的model
    proxyModel=new QSortFilterProxyModel;
    proxyModel->setSourceModel(stringlistModel);  //设置源model 为stringlistModel
    proxyModel->setFilterKeyColumn(0);  //顾名思义,设置key筛选内容时候是通过第一列
    view=new QListView;
    view->setModel(proxyModel);  //设置view的model是proxyModel,proxyModel作为view和stringlistModel的桥梁
    //以上已经把view--model模型建立起来
    QLineEdit *filterEdit=new QLineEdit;
    QLabel *filterLabel=new QLabel;
    filterLabel->setText(tr("过滤器:"));
    QHBoxLayout *Hlayout1=new QHBoxLayout;
    Hlayout1->addWidget(filterLabel);
    Hlayout1->addWidget(filterEdit);
    comboBox=new QComboBox;
    comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);  //设置组合框的显示属性
    comboBox->addItem(tr("正则表达式"),QRegExp::RegExp);  //第二个参数是用户定义参数,正则表达式来筛选
    comboBox->addItem(tr("通配符"),QRegExp::Wildcard);  //通配符来筛选
    comboBox->addItem(tr("字符串匹配"),QRegExp::FixedString);  //字符串匹配
    QLabel *comLabel=new QLabel(tr("筛选语法"));
    QHBoxLayout *Hlayout2=new QHBoxLayout;
    Hlayout2->addWidget(comLabel);
    Hlayout2->addWidget(comboBox);
    QVBoxLayout *vboxlayout=new QVBoxLayout;
    vboxlayout->addWidget(view);
    vboxlayout->addLayout(Hlayout1);
    vboxlayout->addLayout(Hlayout2);
    this->setLayout(vboxlayout);
    connect(filterEdit,SIGNAL(textChanged(QString)),this,SLOT(syntaxChange(QString)));
}
Dialog::~Dialog()
{
    delete ui;
}
void Dialog::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
void Dialog::syntaxChange(QString text)
{
    //在这里要根据组合框中的内容重新设置过滤器语法,因此要先将组何况中的数据去出来,然后构造setFilterRegExp()的参数
    //也就是QRegExp 对象,而QRegExp 的第三个参数就是组合框中的语法
    QRegExp::PatternSyntax Psyntax=QRegExp::PatternSyntax(comboBox->itemData(comboBox->currentIndex()).toInt());                                           //将QVirant数据转换成int型的,该参数为QRegExp构造函数的第三个参数
    QRegExp syntax=QRegExp(text,Qt::CaseInsensitive,Psyntax);
    proxyModel->setFilterRegExp(syntax);  //设置过滤语法
}
至于main()函数的内容,由于和前面的代码几乎是一样的,这里就不再贴出来了。我们使用的是QColor::colorNames()函数提供的数据。这个函数返回值是一个QStringList类型的变量,可以给出预定义的颜色的名字。我们使用一个QStringListModel包装这个数据,这和前面的内容没有什么区别。然后创建一个QSortFilterProxyModel对象,使用它的setSourceModel()函数将前面定义的QStringListModel传进去,也就是我们需要对这个model进行代理。那么我们需要过滤哪一列呢?虽然QStringListModel只有一列,但是我们也需要使用setFilterKeyColumn()函数设置一下,以便让这个proxy知道要过滤的是第0列。最后重要的一点是,QListView的model必须设置为QSortFilterProxyModel,否则是看不到效果的。
 
下面的QLineEdit提供过滤数据的输入,这个没什么好说的。后面的QComboBox列出了三项:
comboBox->addItem(tr("正则表达式"),QRegExp::RegExp); 
comboBox->addItem(tr("通配符"),QRegExp::Wildcard); 
comboBox->addItem(tr("字符串匹配"),QRegExp::FixedString); 
这是正则表达式的类型。正则表达式有一套通用的语法,但是对于不同的环境,正则表达式的规则可能是不一样的。第一个QregExp::RegExp提供了最一般的正则表达式语法,不过这个语法不支持贪婪限定符。这也是Qt默认的规则。如果你需要使用贪婪限定符,需要使用QRegExp::RegExp2,根据文档描述,这个将会是 Qt5 的默认规则。第二个是Unix下shell很常见的一种规则。第三个即固定表达式,也就是说基本上不使用正则表达式的。
 
我们使用connect()函数,将QLineEdit的textChanged()信号同slot连接起来。其中我们的slot函数如下所示:
void Dialog::syntaxChange(QString text)
{
   
//在这里要根据组合框中的内容重新设置过滤器语法,因此要先将组何况中的数据去出来,然后构造setFilterRegExp()的参数
    //也就是QRegExp 对象,而QRegExp 的第三个参数就是组合框中的语法
    QRegExp::PatternSyntax Psyntax=QRegExp::PatternSyntax(comboBox->itemData(comboBox->currentIndex()).toInt());                                          //将QVirant数据转换成int型的,该参数为QRegExp构造函数的第三个参数
    QRegExp syntax=QRegExp(text,Qt::CaseInsensitive,Psyntax);
    proxyModel->setFilterRegExp(syntax); 
//设置过滤语法
}
第一步,使用QComboBox的选择值创建一个QRegExp::PatternSyntax对象,然后利用这个语法规则构造一个正则表达式,注意我们在QLineEdit里面输入的内容是通过参数传递进来的,然后设置proxy的过滤器的表达式。好了,就这样运行一下看看效果吧!

你可能感兴趣的:(UI,正则表达式,dialog,qt,wildcard,Signal)