0. 源代码下载
https://github.com/leichaojian/qt/tree/master/Window
1. 程序效果图
当我们选择:大小写不敏感,以列Subject作为筛选对象,以常规的正则表达式作为过滤条件情况下,输出为:
2. 源代码解析
1. 界面排布
分为original Model和Sorted/Filterd Model两部分。Sorted/Filterd Model的布局如下:
QGridLayout *proxyLayout = new QGridLayout;
//addWidget后四个参数表示:proxyView的位置是0行0列,其中行占用1行,列占用3列
proxyLayout->addWidget(proxyView, 0, 0, 1, 3);
proxyLayout->addWidget(filterPatternLabel, 1, 0);
proxyLayout->addWidget(filterPatternLineEdit, 1, 1, 1, 2);
proxyLayout->addWidget(filterSyntaxLabel, 2, 0);
proxyLayout->addWidget(filterSyntaxComboBox, 2, 1, 1, 2);
proxyLayout->addWidget(filterColumnLabel, 3, 0);
proxyLayout->addWidget(filterColumnComboBox, 3, 1, 1, 2);
proxyLayout->addWidget(filterCaseSensitivityCheckBox, 4, 0, 1, 2);
proxyLayout->addWidget(sortCaseSensitivityCheckBox, 4, 2);
proxyGroupBox->setLayout(proxyLayout);
这里使用QGridLayout来布局。而通过addWidget来进行排布:
void QGridLayout::addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0)
在QGrid中布局widget,从fromRow行fromColumn列开始,而fromRow横跨rowSpan行,fromColumn横跨columnSpan列。
而original Model则相对简单:
model->insertRow(0);
//这里是在model的第0行0,1,2列插入数据--则会将数据插入到sourceGroupBox中去
model->setData(model->index(0, 0), subject);
model->setData(model->index(0, 1), sender);
model->setData(model->index(0, 2), date);
这里将数据直接写到
original Model中去。通过:
mainLayout->addWidget(sourceGroupBox);
mainLayout->addWidget(proxyGroupBox);
setLayout(mainLayout);
来完成最终的排序。
2. 关键代码解析
1. 当用于排序或者过滤的列名改变的时候,需要改变排序的属性(比如以Subject来排序,而后来修改为以Sender来排序)
void Window::filterColumnChanged()
{
proxyModel->setFilterKeyColumn(filterColumnComboBox->currentIndex());
}
其中setFilterKeyColumn将其参数的列名作为排序/过滤的标准。
2. 对于大小写是否敏感的判断
void Window::sortChanged()
{
proxyModel->setSortCaseSensitivity(
sortCaseSensitivityCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive);
}
3. 正则表达式排序的关键代码
void Window::filterRegExpChanged()
{
//使用正则表达式中的Regular expression,Wildcard还是Fixed string三种过滤标准
QRegExp::PatternSyntax syntax =
QRegExp::PatternSyntax(filterSyntaxComboBox->itemData(
filterSyntaxComboBox->currentIndex()).toInt());
//是否大小写敏感
Qt::CaseSensitivity caseSensitivity =
filterCaseSensitivityCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive;
QRegExp regExp(filterPatternLineEdit->text(), caseSensitivity, syntax);
proxyModel->setFilterRegExp(regExp);
}