The reason for this behavior is that you're using the wrong row in beginRemoveRows()
: you should use the row number you're removing, and since you're using rowCount()
that row index is invalid.
def removeItems(self, items):
self.beginRemoveRows(QtCore.QModelIndex(), self.rowCount() - 1, self.rowCount() - 1)
self.items = [x for x in self.items if x not in items]
self.endRemoveRows()
To be more correct, you should remove the actual rows in the model. In your simple case it won't matter that much, but in case your model becomes more complex, keep in mind this.
def removeItems(self, items):
removeRows = []
for row, item in enumerate(self.items):
if item in items:
removeRows.append(row)
for row in sorted(removeRows, reverse=True):
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
self.items.pop(row)
self.endRemoveRows()
The reason for the reversed row order in the for cycle is that for list consistency reasons the row removal should always begin from the bottom. This can be important if you want to remove rows arbitrarily while keeping the current selection in case the removed items are not selected.
That said, as already suggested in the comments, if you don't need specific behavior and implementation, creating a QAbstractItemModel (or any abstract model) subclass is unnecessary, as QStandardItemModel will usually be enough, as it already provides all required features (including drag and drop support, which can be rather complex if you don't know how the Qt data model works).
Well, unless it's for learning purposes, obviously.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…