Проблема с фильтром QSortFilterProxyModel

#python #python-3.x #qt5 #pyqt5

#python #python-3.x #qt5 #pyqt5

Вопрос:

Используя QSortFilterProxyModel, мне нужно отфильтровать данные на основе значения определенного столбца; однако столбец может содержать несколько значений. Мне не нужно показывать строку, если столбец содержит определенное значение. Нужно ли мне создавать подкласс QSortFilterProxyModel и переопределять метод filterAcceptsRow() или мне следует использовать setFilterRegExp?

Столбец может содержать целые числа: 0,1,2,3. Если столбец содержит 2, то мне не нужно показывать строку.

Ответ №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()
  

Вы даже можете настроить свою модель фильтра так, чтобы она принимала функцию лямбда-фильтра

Комментарии:

1. Спасибо jgoday. Я ценю помощь!

Ответ №2:

Согласно вашему описанию, вы должны создать подкласс 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)