당신은 QSortFilterProxyModel
에서 상속하는 클래스를 만들고, 모두가 만족하는 경우 하나 개 이상의 항목을 만족하고 사실이 아닌 경우 거짓이 반환되는 filterAcceptsRow
방법을 덮어 써야합니다.
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_())
쿨 친구 ,,,,이 ,,, 감사합니다 :) –
야 어떻게 한 번에 모든 열 필터를 취소 작동? 필터 재설정 또는 필터 지우기 같은 옵션이 있습니까 ?? @eyllanesc –
개별적인 경우와 동일합니다. 빈 문자열을 필터링하는 열을 전달해야합니다. – eyllanesc