How to filter Multiple column in Qtableview?

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

I'm using QtableView to show my logs and to filter them by column, QSortFilterProxyModel is used. If i filter one column using certain value, and with the filtered data, if i try to filter second column, last filter gets reset and data are displayed corresponding to filter on second column. I want to achieve multiple column filter on Qtableview.

Code snippet:

self.tableView = QTableView() self.model = QtGui.QStandardItemModel(self) self.proxy = QtGui.QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) self.tableView.setModel(self.proxy)  def updateTable(self):     self.model.invisibleRootItem().appendRow(,,,,)  def filterTable(self, stringAction, filterColumn):     filterString = QtCore.QRegExp(  stringAction,                                     QtCore.Qt.CaseSensitive,                                     QtCore.QRegExp.FixedString                                     )      self.proxy.setFilterRegExp(filterString)     self.proxy.setFilterKeyColumn(filterColumn) 

回答1:

You must create a class that inherits from QSortFilterProxyModel, and overwrite the filterAcceptsRow method where False is returned if at least one item is not satisfied and True if all are satisfied.

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 

Example:

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_()) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!