使用QSortFilterProxyModel我需要基于特定列的值来过滤数据。但是,该列可能包含多个值。如果列包含特定值,则无需显示该行。我是否需要对QSortFilterProxyModel进行子类化并重写filterAcceptsRow()方法,还是应该使用setFilterRegExp?
该列可以包含整数:0、1、2、3。如果该列包含2,则无需显示该行。
答案 0 :(得分:1)
如果您将数据存储为QList或列表,则可以轻松地将QSortFilterProxyModel子类化以检查每一行中的此列表
这是一个简单的例子:
import sys
from PyQt5.QtCore import QSortFilterProxyModel,Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QListView, QApplication
app = QApplication(sys.argv)
list = QListView()
list.setWindowTitle('sample')
list.setMinimumSize(600, 400)
model = QStandardItemModel(list)
for i in range(1, 10):
# create each item with a list attached to the Qt::UserRole + 1
item = QStandardItem(str(i))
item.setData([i, i*2], Qt.UserRole + 1)
model.appendRow(item)
class MyFilterModel(QSortFilterProxyModel):
def filterAcceptsRow(self, source_row, source_parent):
i = self.sourceModel().index(source_row, 0, source_parent)
data = self.sourceModel().data(i, Qt.UserRole + 1)
print(data)
return 2 not in data
filter_model = MyFilterModel()
filter_model.setSourceModel(model)
list.setModel(filter_model)
list.show()
app.exec()
您甚至可以自定义过滤器模型以接受lambda过滤器功能
答案 1 :(得分:0)
根据你的描述,你应该继承QSortFilterProxyModel并覆盖filterAcceptsRow(),下面是表模型的简单代理模型:
class DemoProxyModel(QSortFilterProxyModel):
"""
"""
def __init__(self, parent=None):
super().__init__(parent)
def filterAcceptsRow(self, sourceRow, sourceParent):
"""custom filtering"""
if not self.filterRegExp().isEmpty():
model_source = self.sourceModel()
if model_source is None:
return False
# pick up the column that you want to filter, e.g., column 3
index0 = model_source.index(sourceRow, 3, sourceParent)
data0 = model_source.data(index0)
# return self.filterRegExp() == data_type # equal match, the tight binding
return self.filterRegExp().indexIn(data0) >= 0 # include match, the loose binding
# return data_type.__contains__(self.filterRegExp()) # include match, the loose binding
# parent call for initial behaviour
return super().filterAcceptsRow(sourceRow, sourceParent)