Несколько фильтров в столбцах с QSortFilterProxyModel в PyQt5 [дубликат]

Оператор == всегда предназначен для сравнения ссылок на объекты, тогда как метод сравнения строк .equals () переопределяется для сравнения содержимого:

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
1
задан Anand 9 November 2017 в 13:22
поделиться

1 ответ

Вы должны создать класс, который наследует от QSortFilterProxyModel, и перезаписать метод filterAcceptsRow, где возвращается False, если хотя бы один элемент не выполняется, и True, если все выполнено.

class SortFilterProxyModel(QSortFilterProxyModel):
    def __init__(self, *args, **kwargs):
        QSortFilterProxyModel.__init__(self, *args, **kwargs)
        self.filters = {}

    def setFilterByColumn(self, regex, column):
        self.filters[column] = regex
        self.invalidateFilter()

    def filterAcceptsRow(self, source_row, source_parent):
        for key, regex in self.filters.items():
            ix = self.sourceModel().index(source_row, key, source_parent)
            if ix.isValid():
                text = self.sourceModel().data(ix).toString()
                if not text.contains(regex):
                    return False
        return True

Пример:

def random_word():
    letters = "abcdedfg"
    word = "".join([choice(letters) for _ in range(randint(4, 7))])
    return word


class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.setLayout(QVBoxLayout())

        tv1 = QTableView(self)
        tv2 = QTableView(self)
        model = QStandardItemModel(8, 4, self)
        proxy = SortFilterProxyModel(self)
        proxy.setSourceModel(model)
        tv1.setModel(model)
        tv2.setModel(proxy)
        self.layout().addWidget(tv1)
        self.layout().addWidget(tv2)

        for i in range(model.rowCount()):
            for j in range(model.columnCount()):
                item = QStandardItem()
                item.setData(random_word(), Qt.DisplayRole)
                model.setItem(i, j, item)

        flayout = QFormLayout()
        self.layout().addLayout(flayout)
        for i in range(model.columnCount()):
            le = QLineEdit(self)
            flayout.addRow("column: {}".format(i), le)
            le.textChanged.connect(lambda text, col=i:
                                   proxy.setFilterByColumn(QRegExp(text, Qt.CaseSensitive, QRegExp.FixedString),
                                                           col))


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
3
ответ дан eyllanesc 16 August 2018 в 11:47
поделиться
  • 1
    Прохладный чувак ,,,, он работает ,,, спасибо :) – Anand 10 November 2017 в 05:56
  • 2
    Эй, как очистить все фильтры столбцов за раз? есть ли какой-либо вариант, например, сброс фильтра или очистка фильтров? @eyllanesc – Anand 10 November 2017 в 07:01
  • 3
    Это то же самое, что и в отдельном случае, вы должны перейти к столбцам, которые фильтруют пустую строку – eyllanesc 10 November 2017 в 08:20
  • 4
    да ,, Готово :) – Anand 10 November 2017 в 08:26
Другие вопросы по тегам:

Похожие вопросы: