#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' PyQt4 conversion of Qt Basic Sort/Filter Example The Basic Sort/Filter Model example illustrates how to use QSortFilterProxyModel to perform basic sorting and filtering. BEHAVIOUR: ========= Filter options are implemented. Try different regular expressions, change the filter column or the sort column. NOTES: ===== Implemented private slots: _filterRegExpChanged() _filterColumnChanged() _sortChanged() Redefined filterSyntaxComboBox, filterCaseSensitivityCheckBox, sortCaseSensitivityCheckBox, filterSyntaxComboBox and filterPatternLineEdit as attributes. last modified: 2012-01-30 jg ref: http://developer.qt.nokia.com/doc/qt-4.8/itemviews-basicsortfiltermodel.html ''' from PyQt4.QtGui import (QApplication, QWidget, QGroupBox, QHBoxLayout, QLabel, QVBoxLayout, QGridLayout, QTreeView, QSortFilterProxyModel, QCheckBox, QLineEdit, QComboBox, QStandardItemModel) from PyQt4.QtCore import (Qt, pyqtSlot, QRegExp, QDateTime, QDate, QTime) class Window(QWidget): def __init__(self, parent=None): # initialise base class super(Window, self).__init__(parent) layout = QVBoxLayout() layout.addWidget(self._createSourcePanel()) layout.addWidget(self._createProxyPanel()) self.setLayout(layout) # set initial filter column and regexp self._filterColumnComboBox.setCurrentIndex(1) self._filterPatternLineEdit.setText("Grace|Andy") # public methods ---------------------------------------------------------- def setSourceModel(self, model): self._proxyModel.setSourceModel(model) self._sourceView.setModel(model) # private methods --------------------------------------------------------- def _createSourcePanel(self): sourceGroupBox = QGroupBox(self.tr("Original Model")) self._sourceView = QTreeView() self._sourceView.setRootIsDecorated(False) self._sourceView.setAlternatingRowColors(True) sourceLayout = QHBoxLayout() sourceLayout.addWidget(self._sourceView) sourceGroupBox.setLayout(sourceLayout) return sourceGroupBox def _createProxyPanel(self): proxyGroupBox = QGroupBox(self.tr("Sorted/Filter Model")) proxyView = QTreeView() proxyView.setRootIsDecorated(False) proxyView.setAlternatingRowColors(True) proxyView.sortByColumn(1, Qt.AscendingOrder) self._proxyModel = QSortFilterProxyModel() self._proxyModel.setDynamicSortFilter(True) proxyView.setModel(self._proxyModel) proxyView.setSortingEnabled(True) # click col hdr to sort proxyLayout = QVBoxLayout() proxyLayout.addWidget(proxyView) proxyLayout.addLayout(self._createProxyFilterPanel()) proxyGroupBox.setLayout(proxyLayout) return proxyGroupBox def _createProxyFilterPanel(self): self._sortCaseSensitivityCheckBox = QCheckBox(self.tr("Case sensitive sorting")); self._filterCaseSensitivityCheckBox = QCheckBox(self.tr("Case sensitive filter")); # default for case sensitivity is true so check boxes self._sortCaseSensitivityCheckBox.setChecked(True) self._filterCaseSensitivityCheckBox.setChecked(True) self._filterPatternLineEdit = QLineEdit(); filterPatternLabel = QLabel(self.tr("&Filter pattern:")); filterPatternLabel.setBuddy(self._filterPatternLineEdit); self._filterSyntaxComboBox = QComboBox(); self._filterSyntaxComboBox.addItem(self.tr("Regular expression"), QRegExp.RegExp); self._filterSyntaxComboBox.addItem(self.tr("Wildcard"), QRegExp.Wildcard); self._filterSyntaxComboBox.addItem(self.tr("Fixed string"), QRegExp.FixedString); filterSyntaxLabel = QLabel(self.tr("Filter &syntax:")); filterSyntaxLabel.setBuddy(self._filterSyntaxComboBox); self._filterColumnComboBox = QComboBox(); self._filterColumnComboBox.addItem(self.tr("Subject")); self._filterColumnComboBox.addItem(self.tr("Sender")); self._filterColumnComboBox.addItem(self.tr("Date")); filterColumnLabel = QLabel(self.tr("Filter &column:")); filterColumnLabel.setBuddy(self._filterColumnComboBox); # connect signals/slots for event handling self._filterPatternLineEdit.textChanged.connect(self._filterRegExpChanged) self._filterSyntaxComboBox.currentIndexChanged.connect(self._filterRegExpChanged) self._filterColumnComboBox.currentIndexChanged.connect(self._filterColumnChanged) self._filterCaseSensitivityCheckBox.toggled.connect(self._filterRegExpChanged) self._sortCaseSensitivityCheckBox.toggled.connect(self._sortChanged) grid = QGridLayout() grid.addWidget(filterPatternLabel, 0, 0) grid.addWidget(self._filterPatternLineEdit, 0, 1) grid.addWidget(filterSyntaxLabel, 1, 0) grid.addWidget(self._filterSyntaxComboBox, 1, 1) grid.addWidget(filterColumnLabel, 2, 0) grid.addWidget(self._filterColumnComboBox, 2, 1) grid.addWidget(self._filterCaseSensitivityCheckBox, 3, 0) grid.addWidget(self._sortCaseSensitivityCheckBox, 3, 1, Qt.AlignRight) return grid # private slots ----------------------------------------------------------- @pyqtSlot() def _filterRegExpChanged(self): # get the QRegEx.PatternSyntax enum value # 0 - Regular Expression # 1 - Wildcard # 2 - Fixed String syntax = self._filterSyntaxComboBox.itemData( self._filterSyntaxComboBox.currentIndex()) # get case sensitivity cs = Qt.CaseInsensitive if self._filterCaseSensitivityCheckBox.isChecked(): cs = Qt.CaseSensitive # get user regex pattern pattern = self._filterPatternLineEdit.text() # build filter and update proxy model regExp = QRegExp(pattern, cs, syntax) self._proxyModel.setFilterRegExp(regExp) @pyqtSlot() def _filterColumnChanged(self): self._proxyModel.setFilterKeyColumn( self._filterColumnComboBox.currentIndex()) @pyqtSlot() def _sortChanged(self): cs = Qt.CaseInsensitive if self._sortCaseSensitivityCheckBox.isChecked(): cs = Qt.CaseSensitive self._proxyModel.setSortCaseSensitivity(cs) # createMailModel() ========================================================== def createMailModel(parent): # create, populate and return a 'QStandardItemModel' object model = QStandardItemModel(0, 3, parent) model.setHeaderData(0, Qt.Horizontal, parent.tr("Subject")) model.setHeaderData(1, Qt.Horizontal, parent.tr("Sender")) model.setHeaderData(2, Qt.Horizontal, parent.tr("Date")) addMail(model, "Happy New Year!", "Grace K.", QDateTime(QDate(2006, 12, 31), QTime(17, 3))) addMail(model, "Radically new concept", "Grace K. ", QDateTime(QDate(2006, 12, 22), QTime(9, 44))) addMail(model, "Accounts", "pascale@nospam.com", QDateTime(QDate(2006, 12, 31), QTime(12, 50))) addMail(model, "Expenses", "Joe Bloggs ", QDateTime(QDate(2006, 12, 25), QTime(11, 39))) addMail(model, "Re: Expenses", "Andy ", QDateTime(QDate(2007, 1, 2), QTime(16, 5))) addMail(model, "Re: Accounts", "Joe Bloggs ", QDateTime(QDate(2007, 1, 3), QTime(14, 18))) addMail(model, "Re: Accounts", "Andy ", QDateTime(QDate(2007, 1, 3), QTime(14, 26))) addMail(model, "Sports", "Linda Smith ", QDateTime(QDate(2007, 1, 5), QTime(11, 33))) addMail(model, "AW: Sports", "Rolf Newschweinstein ", QDateTime(QDate(2007, 1, 5), QTime(12, 0))) addMail(model, "RE: Sports", "Petra Schmidt ", QDateTime(QDate(2007, 1, 5), QTime(12, 1))) return model # addMail() ================================================================== def addMail(model, subject, sender, date): # insert a row of data into the given model model.insertRow(0) model.setData(model.index(0, 0), subject) model.setData(model.index(0, 1), sender) model.setData(model.index(0, 2), date) # main ======================================================================== def main(): import sys app = QApplication(sys.argv) mw = Window() mw.setSourceModel(createMailModel(mw)) mw.setWindowTitle("Basic Sort/Filter Model - Part 3") mw.resize(500, 450) mw.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
Tuesday, January 31, 2012
Qt 4.8 Basic Sort/Filter Model Example - Part 3
In Part 3 the slots to handle user events are implemented and an initial Regular Expression filter is setup.
Labels:
Qt Basic Sort/Filter