猿问

如何过滤掉单个项目,而不仅仅是在行和列的基础上?

我正在尝试根据字符串匹配过滤掉表中的项目。


我有一个显示代理模型以允许过滤的 QTableView,但是如果 (0,0) 和 (1,1) 中的项目与我的字符串匹配但项目 (1,0) 不匹配,它仍将显示。


例如:


from PySide.QtGui import *

from PySide.QtCore import *



class CustomProxyFilter(QSortFilterProxyModel):


    def __init__(self):

        super(CustomProxyFilter, self).__init__()


    def filterAcceptsColumn(self, source_column, parent):

        """Re-implementing built-in to hide columns with non matches."""

        model = self.sourceModel()

        matched_string = self.filterRegExp().pattern().lower()

        for row in range(model.rowCount()):

            item = model.item(row, source_column)

            if item and matched_string in model.item(row, source_column).text().lower():

                return True

        return False



class CustomTableView(QTableView):

    """Table view."""

    def __init__(self, line_edit):

        super(CustomTableView, self).__init__()


        custom_model = StandardTableModel()


        items = ["apple", "banana", "applebanana"]

        for i, item in enumerate(items):

            for v, second_item in enumerate(items):

                custom_model.setItem(i, v, QStandardItem(item))

        self.proxy_model = CustomProxyFilter()

        self.proxy_model.setSourceModel(custom_model)

        self.setModel(self.proxy_model)



        line_edit.textChanged.connect(self.proxy_model.setFilterRegExp)



class Window(QWidget):


    def __init__(self):

        super(Window, self).__init__()

        self.setLayout(QVBoxLayout())

        self.line_edit = QLineEdit()

        self.layout().addWidget(self.line_edit)

        self.layout().addWidget(CustomTableView(self.line_edit))


我希望会发生的是,如果我的桌子看起来像


a|b|c

-----

c|a|b

按“a”过滤后的结果表将是


a|a

我目前的解决方案显示。


a|b

---

c|a

更新其他案例


a|a|c

-----

a|x|b

-----

c|b|a

变成


a|a|a

-----

a

这个案例


a|a|y|c

-------

a|a|w|a

-------

c|a|w|w

变成


a|a|a|a

-----

a|a|

基本上每个项目都会在可能的情况下向左上角移动。当他们是不同的名字时,他们会像这样按字母顺序排列自己


1|2|3|4

-------

5|6|7|8


HUX布斯
浏览 142回答 1
1回答

眼眸繁星

为了实现您的要求,我通过以下方式实现了几个连接的代理:model-->Table2ListProxyModel-->QSortFilterProxyModel-->List2TableProxyModel想法是将其转换为列表的结构,因为过滤一行相当于过滤一个项目,相同的代理对其进行排序,然后我们将列表转换为表格。import mathfrom PySide import QtCore, QtGuiclass Table2ListProxyModel(QtGui.QSortFilterProxyModel):&nbsp; &nbsp; def columnCount(self, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; return 1&nbsp; &nbsp; def rowCount(self, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; if parent.isValid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0&nbsp; &nbsp; &nbsp; &nbsp; return self.sourceModel().rowCount() * self.sourceModel().columnCount()&nbsp; &nbsp; def mapFromSource(self, sourceIndex):&nbsp; &nbsp; &nbsp; &nbsp; if (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sourceIndex.isValid()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and sourceIndex.column() == 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and sourceIndex.row() < self.rowCount()&nbsp; &nbsp; &nbsp; &nbsp; ):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = sourceIndex.row()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c = sourceIndex.column()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row = c * sourceIndex.model().columnCount() + r&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self.index(row, 0)&nbsp; &nbsp; &nbsp; &nbsp; return QtCore.QModelIndex()&nbsp; &nbsp; def mapToSource(self, proxyIndex):&nbsp; &nbsp; &nbsp; &nbsp; r = proxyIndex.row() / self.sourceModel().columnCount()&nbsp; &nbsp; &nbsp; &nbsp; c = proxyIndex.row() % self.sourceModel().columnCount()&nbsp; &nbsp; &nbsp; &nbsp; return self.sourceModel().index(r, c)&nbsp; &nbsp; def index(self, row, column, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; return self.createIndex(row, column)class List2TableProxyModel(QtGui.QSortFilterProxyModel):&nbsp; &nbsp; def __init__(self, columns=1, parent=None):&nbsp; &nbsp; &nbsp; &nbsp; super(List2TableProxyModel, self).__init__(parent)&nbsp; &nbsp; &nbsp; &nbsp; self._columns = columns&nbsp; &nbsp; def columnCount(self, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; r = self.sourceModel().rowCount()&nbsp; &nbsp; &nbsp; &nbsp; if r < self._columns:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return r&nbsp; &nbsp; &nbsp; &nbsp; return self._columns&nbsp; &nbsp; def rowCount(self, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; if parent.isValid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0&nbsp; &nbsp; &nbsp; &nbsp; row = math.ceil(self.sourceModel().rowCount()*1.0 / self._columns)&nbsp; &nbsp; &nbsp; &nbsp; return row&nbsp; &nbsp; def index(self, row, column, parent=QtCore.QModelIndex()):&nbsp; &nbsp; &nbsp; &nbsp; return self.createIndex(row, column)&nbsp; &nbsp; def data(self, index, role=QtCore.Qt.DisplayRole):&nbsp; &nbsp; &nbsp; &nbsp; r = index.row()&nbsp; &nbsp; &nbsp; &nbsp; c = index.column()&nbsp; &nbsp; &nbsp; &nbsp; row = r * self.columnCount() + c&nbsp; &nbsp; &nbsp; &nbsp; if row < self.sourceModel().rowCount():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return super(List2TableProxyModel, self).data(index, role)&nbsp; &nbsp; def mapFromSource(self, sourceIndex):&nbsp; &nbsp; &nbsp; &nbsp; r = math.ceil(sourceIndex.row()*1.0 / self.columnCount())&nbsp; &nbsp; &nbsp; &nbsp; c = sourceIndex.row() % self.columnCount()&nbsp; &nbsp; &nbsp; &nbsp; return self.index(r, c)&nbsp; &nbsp; def mapToSource(self, proxyIndex):&nbsp; &nbsp; &nbsp; &nbsp; if proxyIndex.isValid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = proxyIndex.row()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c = proxyIndex.column()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row = r * self.columnCount() + c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self.sourceModel().index(row, 0)&nbsp; &nbsp; &nbsp; &nbsp; return QtCore.QModelIndex()&nbsp; &nbsp; def setSourceModel(self, model):&nbsp; &nbsp; &nbsp; &nbsp; model.rowsRemoved.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; model.rowsInserted.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; model.dataChanged.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; model.rowsMoved.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; model.layoutChanged.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; model.modelReset.connect(self.reset_model)&nbsp; &nbsp; &nbsp; &nbsp; super(List2TableProxyModel, self).setSourceModel(model)&nbsp; &nbsp; @QtCore.Slot()&nbsp; &nbsp; def reset_model(self):&nbsp; &nbsp; &nbsp; &nbsp; QtCore.QTimer.singleShot(0, self.invalidate)&nbsp; &nbsp; def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):&nbsp; &nbsp; &nbsp; &nbsp; if role == QtCore.Qt.DisplayRole:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return str(section)&nbsp; &nbsp; &nbsp; &nbsp; return super(List2TableProxyModel, self).headerData(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; section, orientation, role&nbsp; &nbsp; &nbsp; &nbsp; )class CustomTableView(QtGui.QTableView):&nbsp; &nbsp; def __init__(self, parent=None):&nbsp; &nbsp; &nbsp; &nbsp; super(CustomTableView, self).__init__(parent)&nbsp; &nbsp; &nbsp; &nbsp; custom_model = QtGui.QStandardItemModel()&nbsp; &nbsp; &nbsp; &nbsp; datas = (("ad", "cd", "ef"), ("ab", "ce", "eg"), ("aa", "cb", "eh"))&nbsp; &nbsp; &nbsp; &nbsp; for i, data in enumerate(datas):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for v, text in enumerate(data):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; custom_model.setItem(i, v, QtGui.QStandardItem(text))&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_list = Table2ListProxyModel(self)&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_list.setSourceModel(custom_model)&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_sort_filter = QtGui.QSortFilterProxyModel(self)&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_sort_filter.setSourceModel(self.proxy_list)&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_table = List2TableProxyModel(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; columns=custom_model.columnCount(), parent=self&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_table.setSourceModel(self.proxy_sort_filter)&nbsp; &nbsp; &nbsp; &nbsp; self.setModel(self.proxy_table)&nbsp; &nbsp; @QtCore.Slot(str)&nbsp; &nbsp; def setFilter(self, text):&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_sort_filter.setFilterWildcard(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "*{}*".format(text) if text else ""&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; self.proxy_sort_filter.sort(0 if text else -1, QtCore.Qt.AscendingOrder)class Window(QtGui.QWidget):&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; &nbsp; &nbsp; super(Window, self).__init__()&nbsp; &nbsp; &nbsp; &nbsp; self.line_edit = QtGui.QLineEdit()&nbsp; &nbsp; &nbsp; &nbsp; self.tableview = CustomTableView()&nbsp; &nbsp; &nbsp; &nbsp; lay = QtGui.QVBoxLayout(self)&nbsp; &nbsp; &nbsp; &nbsp; lay.addWidget(self.line_edit)&nbsp; &nbsp; &nbsp; &nbsp; lay.addWidget(self.tableview)&nbsp; &nbsp; &nbsp; &nbsp; self.line_edit.textChanged.connect(self.tableview.setFilter)if __name__ == "__main__":&nbsp; &nbsp; import sys&nbsp; &nbsp; app = QtGui.QApplication(sys.argv)&nbsp; &nbsp; w = Window()&nbsp; &nbsp; w.show()&nbsp; &nbsp; sys.exit(app.exec_())
随时随地看视频慕课网APP

相关分类

Python
我要回答