I am having issues trying to correctly delete multiple selected rows from a QListView. It works correctly selecting items going from top to bottom, but when you select multiple rows going from bottom to top, it keeps one of the selected rows in the view.
How can I fix this to where it correctly removes all selected rows in any order the user chooses?
Example:
Selecting the rows in this order gives an invalid solution: Level5, Level3, Level2
Removes only Level2
Changing to for items in self.listView.selectedIndexes():
works the opposite to where you cannot select from top to bottom.
from PyQt5 import QtCore, QtGui, QtWidgets
import sys,functools
class Window(QtWidgets.QMainWindow):
def __init__(self, parent = None):
super(Window,self).__init__(parent)
self.setCentralWidget(QtWidgets.QWidget(self))
self.setWindowTitle('GUI')
mainlayout = QtWidgets.QVBoxLayout()
#Information for widgets
self.items = {'Level1':1,'Level2':2,'Level3':3,'Level4':4,'Level5':5,'Level6':6}
#LineEdit1
self.button = QtWidgets.QPushButton()
self.button.setText('Remove Selected Items')
firstBox = QtWidgets.QHBoxLayout()
firstBox.addWidget(self.button)
#ListView
self.listView = QtWidgets.QListView()
self.listView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
secondBox = QtWidgets.QVBoxLayout()
secondBox.addWidget(self.listView)
#Add Layouts
mainlayout.addLayout(firstBox)
mainlayout.addLayout(secondBox)
self.centralWidget().setLayout(mainlayout)
#Model
self.model = QtGui.QStandardItemModel()
self.listView.setModel(self.model)
self.button.clicked.connect(functools.partial(self.selecteditems,self.model))
self.fillModel(self.model)
def fillModel(self,model):
for level in self.items:
item = QtGui.QStandardItem(str(level))
model.appendRow(item)
def selecteditems(self,model):
if len(self.listView.selectedIndexes()) > 1:
for items in reversed(self.listView.selectedIndexes()):
model.takeRow(items.row()) #works correctly selecting items from top to bottom, but doesn't work when selecting bottom to top
def main():
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
you can also use just reversed
and sorted
:
def selecteditems(self,model):
if len(self.listView.selectedIndexes()) > 1:
for items in reversed(sorted(self.listView.selectedIndexes())):
model.takeRow(items.row())