Last active
December 1, 2022 22:11
-
-
Save dbridges/4732790 to your computer and use it in GitHub Desktop.
A subclass of QSortFilterProxyModel that implements custom filtering, especially useful for multicolumn filtering.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PySide import QtGui | |
class CustomSortFilterProxyModel(QtGui.QSortFilterProxyModel): | |
""" | |
Implements a QSortFilterProxyModel that allows for custom | |
filtering. Add new filter functions using addFilterFunction(). | |
New functions should accept two arguments, the column to be | |
filtered and the currently set filter string, and should | |
return True to accept the row, False otherwise. | |
Filter functions are stored in a dictionary for easy | |
removal by key. Use the addFilterFunction() and | |
removeFilterFunction() methods for access. | |
The filterString is used as the main pattern matching | |
string for filter functions. This could easily be expanded | |
to handle regular expressions if needed. | |
""" | |
def __init__(self, parent=None): | |
super(CustomSortFilterProxyModel, self).__init__(parent) | |
self.filterString = '' | |
self.filterFunctions = {} | |
def setFilterString(self, text): | |
""" | |
text : string | |
The string to be used for pattern matching. | |
""" | |
self.filterString = text.lower() | |
self.invalidateFilter() | |
def addFilterFunction(self, name, new_func): | |
""" | |
name : hashable object | |
The object to be used as the key for | |
this filter function. Use this object | |
to remove the filter function in the future. | |
Typically this is a self descriptive string. | |
new_func : function | |
A new function which must take two arguments, | |
the row to be tested and the ProxyModel's current | |
filterString. The function should return True if | |
the filter accepts the row, False otherwise. | |
ex: | |
model.addFilterFunction( | |
'test_columns_1_and_2', | |
lambda r,s: (s in r[1] and s in r[2])) | |
""" | |
self.filterFunctions[name] = new_func | |
self.invalidateFilter() | |
def removeFilterFunction(self, name): | |
""" | |
name : hashable object | |
Removes the filter function associated with name, | |
if it exists. | |
""" | |
if name in self.filterFunctions.keys(): | |
del self.filterFunctions[name] | |
self.invalidateFilter() | |
def filterAcceptsRow(self, row_num, parent): | |
""" | |
Reimplemented from base class to allow the use | |
of custom filtering. | |
""" | |
model = self.sourceModel() | |
# The source model should have a method called row() | |
# which returns the table row as a python list. | |
tests = [func(model.row(row_num), self.filterString) | |
for func in self.filterFunctions.values()] | |
return not False in tests |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@nickgashkov: As wrote on docstrings, you need to use addFilterFunction() and removeFilterFunction() methods for access.
See the exemple in the addFilterFunction method docstring.
@dbridges: To complies with PEP8, the line 75 should be "return False not in tests" but "return all(tests)" may be better ;)