13.6.2 QSortFilterProxyModel的应用(2)
类Window的构造函数如代码段13 26所示,我们只列出了和代理模型相关的部分,省略了创建图13 23界面中各个控件的语句。这个构造函数创建一个代理模型以及两个视图对象,令其中一个视图对象指向刚刚创建的代理模型。默认情况下,视图对象不响应用户的排序请求。为了使能这个功能,行①调用了视图对象的setSortingEnabled()函数。行②后的connect语句将各个控件的信号与类Window的槽函数相连。一旦用户输入或者更改了过滤、排序条件,类Window的相应槽函数将被调用,代理模型将对源模型中的数据项重新进行过滤、排序。
代码段13 26,类Window的构造函数,取自z:\examples\mvc\basicsortfiltermodel\window.cpp
- Window::Window()
- {
- proxyModel = new QSortFilterProxyModel; ……
- sourceView = new QTreeView; ……
- proxyView = new QTreeView; ……
- proxyView->setModel(proxyModel);
- proxyView->setSortingEnabled(true); …… ①
-
- connect(filterPatternLineEdit, SIGNAL(textChanged(QString)), ②
- this, SLOT(filterRegExpChanged()));
- connect(filterSyntaxComboBox, SIGNAL(currentIndexChanged(int)),
- this, SLOT(filterRegExpChanged()));
- connect(filterColumnComboBox, SIGNAL(currentIndexChanged(int)),
- this, SLOT(filterColumnChanged()));
- connect(filterCaseSensitivityCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(filterRegExpChanged()));
- connect(sortCaseSensitivityCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(sortChanged()));
- proxyView->sortByColumn(1, Qt::AscendingOrder); ……
- }
该例子的main()函数在构造完毕Window对象后,调用该类的setSourceModel()函数,令新创建的代理模型指向代码段13 24中创建的源模型,如代码段13 27所示。
代码段13 27,令代理模型指向源模型,取自z:\examples\mvc\basicsortfiltermodel\window.cpp
- void Window::setSourceModel(QAbstractItemModel *model)
- {
- proxyModel->setSourceModel(model);
- sourceView->setModel(model);
- }
当用户更改了过滤或者排序条件时,代码段13 28所定义的类Window的槽函数会被调用。具体来说,当过滤条件变化时,槽函数filterRegExpChanged()会被调用。行①的控件filterSyntaxComboBox是类QComboBox的对象,表示过滤条件的格式。QComboBox负责管理一个组合框。它在屏幕上显示一个输入框以及一个按钮(里面通常显示一个下箭头)。当用户单击按钮时,该控件弹出一个含有若干数据项的列表。用户选择其中一个之后,列表消失,被选择的数据项显示在输入框中。QComboBox使用Model/View框架存放、显示数据。默认情况下,它采用QStandardItemModel存放列表中的数据项,采用QListView显示其中的数据项。虽然我们可以使用模型的接口函数来访问QStandardItemModel中的数据项,但是QComboBox提供了更加方便的访问方式。我们使用以下的方式,向控件filterSyntaxComboBox添加一个数据项,
- filterSyntaxComboBox->addItem(tr("Regular expression"), QRegExp::RegExp);
其中的字符串"Regular expression"被存放在角色DisplayRole对应的数据子项中,而枚举常量QRegExp::RegExp(表示正则表达式格式)被存放在角色UserRole对应的数据子项中。行①调用QComboBo的成员函数currentIndex()返回组合框中第几个数据项被选择,再调用其成员函数itemData()返回该数据项中角色UserRole对应的数据子项,也就是表示过滤条件格式的枚举常量。
行②构造一个正则表达式对象,代理模型在行③使用该对象对源模型中的数据项进行过滤。在槽函数filterColumnChanged()中,行④设置过滤条件施加到源模型的哪个列。
代码段13 28,代理模型对源模型数据项的过滤、排序,取自z:\examples\mvc\basicsortfiltermodel\window.cpp
- void Window::filterRegExpChanged()
- {
- QRegExp::PatternSyntax syntax =
- QRegExp::PatternSyntax(filterSyntaxComboBox->itemData( ①
- filterSyntaxComboBox->currentIndex()).toInt());
- Qt::CaseSensitivity caseSensitivity =
- filterCaseSensitivityCheckBox->isChecked() Qt::CaseSensitive
- : Qt::Case- Insensitive;
- QRegExp regExp(filterPatternLineEdit->text(), caseSensitivity, syntax);②
- proxyModel->setFilterRegExp(regExp); ③
- }
- void Window::filterColumnChanged()
- {
- proxyModel->setFilterKeyColumn(filterColumnComboBox->currentIndex());④
- }
- void Window::sortChanged()
- {
- proxyModel->setSortCaseSensitivity(
- sortCaseSensitivityCheckBox->isChecked() Qt::CaseSensitive
- : Qt::Case- Insensitive);
- }