如何反转 QTableView 选择
How to inverse QTableView selection
下面的代码创建了一个 QTableView 和 QPushButton。单击按钮时,我想切换当前选择(反转它):现在取消选择以前选择的内容,选择以前取消选择的内容。
最后,我想移除(删除)现在选中的行,只留下取消选中的行。
问题:如何实现?
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_()
您必须迭代以获取与每个单元格关联的 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()
注意:@eyllanesc 的回答比较短,
在删除选定的行之前,我们应该知道它们的索引。您可能猜到了,删除一个项目会更改其他项目的索引。
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())
下面的代码创建了一个 QTableView 和 QPushButton。单击按钮时,我想切换当前选择(反转它):现在取消选择以前选择的内容,选择以前取消选择的内容。 最后,我想移除(删除)现在选中的行,只留下取消选中的行。
问题:如何实现?
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_()
您必须迭代以获取与每个单元格关联的 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()
注意:@eyllanesc 的回答比较短,
在删除选定的行之前,我们应该知道它们的索引。您可能猜到了,删除一个项目会更改其他项目的索引。
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())