如何以编程方式退出 QListWidget 中的拖放操作?

How to programmatically back out of a drag-drop operation in a QListWidget?

我正在使用仅显示对象列表的 QListWidget。我允许用户通过内部拖放重新排序这些项目。一切正常,但我现在需要在用户尝试删除(重新排序)时添加一个检查,如果检查失败,则以编程方式重新建立原始订单。这是我得到的:

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)

以上肯定是错误的(我相信),因为它可能重复该项目。但除此之外,问题是它似乎没有效果。我认为 drop 事件覆盖了我在重新排序方面所做的任何事情。但这只是一个理论。有谁知道这样做的正确方法吗?

要还原更改,我们必须首先删除目标项目,为此我们使用 takeItem() 除了删除它之外还会 return 项目,然后在 的帮助下将其插入源位置insertItem() 函数。

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)