代码之家  ›  专栏  ›  技术社区  ›  JokerMartini

QTableview从筛选模型中选择项

  •  0
  • JokerMartini  · 技术社区  · 6 年前

    我有一个QTableView,它使用的是QStandardItemModel。如何在应用/不应用搜索的情况下选择表中的特定行。

    例如,我在搜索栏中键入“y”,以筛选列表,使其仅显示包含字母“y”的行。当我单击“选择Emily”按钮时,考虑到用户可以更改排序顺序,如何使它在tableview中选择正确的行?

    enter image description here

    import sys
    from PySide import QtCore, QtGui
    
    
    class Example(QtGui.QWidget):
    
        def __init__(self, *args, **kwargs):
            super(Example, self).__init__(*args, **kwargs)
            self.resize(400,400)
    
            # controls
            model = QtGui.QStandardItemModel(5, 3)
            model.setHorizontalHeaderLabels(['NAME', 'AGE', 'CAREER'])
    
            people = [
                {'name': 'Kevin', 'age': 5, 'career': 'athlete'},
                {'name': 'Maggie', 'age': 13, 'career': 'banker'},
                {'name': 'Leslie', 'age': 32, 'career': 'banker'},
                {'name': 'Abby', 'age': 32, 'career': 'marketing'},
                {'name': 'Emily', 'age': 45, 'career': 'athlete'},
                {'name': 'David', 'age': 27, 'career': 'banker'},
                {'name': 'Johnny', 'age': 27, 'career': 'soccer'},
                {'name': 'Marie', 'age': 63, 'career': 'secretary'}
            ]
            for row, obj in enumerate(people):
                item = QtGui.QStandardItem(obj['name'])
                model.setItem(row, 0, item)
    
                item = QtGui.QStandardItem(str(obj['age']))
                model.setItem(row, 1, item)
    
                item = QtGui.QStandardItem(obj['career'])
                model.setItem(row, 2, item)
    
            proxy_model = QtGui.QSortFilterProxyModel()
            proxy_model.setSourceModel(model)
    
            # controls
            self.ui_table = QtGui.QTableView()
            self.ui_table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
            self.ui_table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
            self.ui_table.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
            self.ui_table.setModel(proxy_model)
            self.ui_table.setSortingEnabled(False)
            self.ui_table.setSortingEnabled(True)
            self.ui_table.sortByColumn(0, self.ui_table.horizontalHeader().sortIndicatorOrder())
    
            self.ui_search = QtGui.QLineEdit()
            self.ui_selected = QtGui.QPushButton('Select Emily')
    
            # lay main
            lay_main = QtGui.QVBoxLayout()
            lay_main.addWidget(self.ui_search)
            lay_main.addWidget(self.ui_table)
            lay_main.addWidget(self.ui_selected)
            self.setLayout(lay_main)
    
            # connections
            self.ui_selected.clicked.connect(self.clicked_selected_emily)
            self.ui_search.textChanged.connect(self.filter_items)
    
    
        def clicked_selected_emily(self):
            print 'select emily'
            self.ui_table.selectRow(2)
    
        def filter_items(self, text):
            rows = self.ui_table.model().rowCount()
            for row in range(rows):
                self.filter_row(row, text)
    
    
        def filter_row(self, row, pattern):
            if not pattern:
                self.ui_table.setRowHidden(row, False)
                return
    
            model = self.ui_table.model()
            columns = model.columnCount()
            stringlist = []
    
            # collect text from all columns into single string for searching
            for c in range(columns):
                mdx = model.index(row, c)
                if mdx.isValid():
                    val = str(mdx.data(role=QtCore.Qt.DisplayRole)).lower()
                    stringlist.append(val)
    
            # search for string
            patterns = filter(None, [x.lower() for x in pattern.split(' ')])
            results = all(any(x in y for y in stringlist) for x in patterns)
            if results:
                self.ui_table.setRowHidden(row, False)
            else:
                self.ui_table.setRowHidden(row, True)
    
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        ex = Example()
        ex.show()
        sys.exit(app.exec_())
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc RAHUL KUMAR    6 年前

    你必须使用 match() 模型方法:

    def clicked_selected_emily(self):
        print("select emily")
        self.ui_table.clearSelection()
        indexes = self.ui_table.model().match(
            self.ui_table.model().index(0, 0),
            QtCore.Qt.DisplayRole, # role of the search, the text uses the role Qt::DisplayRole
            "Emily", # value that is being searched in the model.
            -1, # maximum number of values ​​are being searched, if it is -1 it will search for all the matches
            QtCore.Qt.MatchExactly # type of search
        )
        for ix in indexes:
            self.ui_table.selectRow(ix.row())
    

    更新:

    默认情况下,搜索是传递给 self.ui_table.model().index(0, col) 在上一个示例中,如果要搜索所有列,则只应在这些列上迭代,为了观察效果,启用了multiselection:

        self.ui_table.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
    
    ...
    
    def clicked_selected_emily(self):
        print("select banker")
        self.ui_table.clearSelection()
        word = "banker"
    
        for i in range(self.ui_table.model().columnCount()):
            indexes = self.ui_table.model().match(
                self.ui_table.model().index(0, i),
                QtCore.Qt.DisplayRole, # role of the search, the text uses the role Qt::DisplayRole
                "banker", # value that is being searched in the model.
                -1, # maximum number of values ​​are being searched, if it is -1 it will search for all the matches
                QtCore.Qt.MatchExactly # type of search
            )
            for ix in indexes:
                self.ui_table.selectRow(ix.row())
    

    enter image description here

    推荐文章