I'm using a QListWidget that simply displays a list of objects. I allow the user to reorder these items via internal drag and drop. Everything works, but I now need to add a check when the user tries to drop (reorder) and if the check fails, re-establish the original order programmatically. Here's what I've got:
class SequenceControl(QListWidget):
def __init__(self, parent = None):
super(SequenceControl, self).__init__(parent)
self.initialIndex = 0
self.selectedObject = None
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
def dragEnterEvent(self, event):
super(SequenceControl, self).dragEnterEvent(event)
self.selectedObject = self.currentItem()
self.initialIndex = self.currentRow()
def dropEvent(self, event):
super(SequenceControl, self).dropEvent(event)
# Some logic here (not shown) to see if the drop is not
# allowed. Assume it isn't:
warningDialog = MyWarningDialog(self.parent)
ProceedAnyway = warningDialog.exec_()
if ProceedAnyway:
# Do stuff...
else:
# Here's the problem. I need to place the item being dropped
# back in its initial pre-drag/drop location. The following
# naïve attempt doesn't work:
self.insertItem(self.initialIndex, self.selectedObject)
The above is definitely wrong (I believe) because it may duplicate the item. But aside from that, the problem is that it appears to have no effect. I think the drop event is overriding anything I'm doing in terms of reordering. But that's just a theory. Does anyone know the right way to do this?
To revert the change we must first remove the target item, for this we use takeItem()
that besides removing it will return the item, then insert it in the source position with the help of the insertItem()
function.
class SequenceControl(QListWidget):
def __init__(self, parent=None):
super(SequenceControl, self).__init__(parent)
self.fromPos = None
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
def dragEnterEvent(self, event):
super(SequenceControl, self).dragEnterEvent(event)
self.fromPos = self.currentRow()
def dropEvent(self, event):
super(SequenceControl, self).dropEvent(event)
reply = QMessageBox.question(None, "Revert to Drag and Drop",
"Do you want to keep the change?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
print("Do stuff...")
else:
currentItem = self.takeItem(self.currentRow())
self.insertItem(self.fromPos, currentItem)