如何反转QTableView选择

时间:2018-04-03 21:04:49

标签: python qt pyqt tableview qstandarditemmodel

下面的代码创建了一个QTableView和QPushButton。单击按钮时,我想切换当前选择(反过来):现在取消选择以前选择的内容,并选择以前取消选择的内容。 最后,我想删除(删除)现在选择的行,只留下那些被取消选择的行。

问题:如何实现?

enter image description here

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
app = QApplication([])


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setLayout(QVBoxLayout())
        self.view = QTableView(self)
        self.view.setSelectionBehavior(QTableWidget.SelectRows)
        self.view.setSortingEnabled(True)
        self.view.sortByColumn(0, Qt.DescendingOrder)

        self.view.setModel(QStandardItemModel(4, 4))
        for each in [(row, col, QStandardItem('item %s_%s' % (row, col))) for row in range(4) for col in range(4)]:
            self.view.model().setItem(*each)

        self.layout().addWidget(self.view)

        btn1 = QPushButton('Invert selection then remove what selected')
        btn1.clicked.connect(self.invertSelectionRemoveSelected)
        self.layout().addWidget(btn1)
        self.resize(500, 250)
        self.show()

    def invertSelectionRemoveSelected(self):
        print 'invertSelectionRemoveSelected'


dialog = Dialog()
app.exec_()

2 个答案:

答案 0 :(得分:2)

您必须迭代才能获得与每个单元格关联的QModelIndex,并使用QItemSelection反转每个单元格的选择。

def invertSelectionRemoveSelected(self):
    model = self.view.model()
    for i in range(model.rowCount()):
        for j in range(model.columnCount()):
            ix = model.index(i, j)
            self.view.selectionModel().select(ix, QItemSelectionModel.Toggle)
    # delete rows
    for ix in reversed(self.view.selectionModel().selectedRows()):
        model.removeRow(ix.row())

另一种解决方案:

根据您的要求,我了解您要删除未选择的行,然后取消选择所有其他行。所以下一个解决方案直接做到了。

def invertSelectionRemoveSelected(self):
    model = self.view.model()
    rows_selected =[ix.row() for ix in self.view.selectionModel().selectedRows()]
    [model.removeRow(i) for i in reversed(range(model.rowCount())) if i not in rows_selected]
    self.view.clearSelection()

答案 1 :(得分:1)

注意:@ eyllanesc的答案较短, here

在删除选定的行之前,我们应该知道它们的索引。正如您可能猜到的,删除项目会更改其他索引。

def invertSelectionRemoveSelected(self):
    #from @eyllanesc's answer, inverse selected items
    model = self.view.model()
    for i in range(model.rowCount()):
        for j in range(model.columnCount()):
            ix = model.index(i, j)
            self.view.selectionModel().select(ix, QItemSelectionModel.Toggle)

    #delete selected items
    index_list = []
    for model_index in self.view.selectionModel().selectedRows():
        index = QPersistentModelIndex(model_index)
        index_list.append(index)
    for index in index_list:
        model.removeRow(index.row())
相关问题