PyQt 信号跟踪 QTableView 中的行何时被移动

PyQt signal to track when row in QTableView was moved

我正在使用带有 QTableViewQAbstractItemModel 的子类版本,并使用子类 model.dropMimeData()model.insertRows()、[=15 激活了拖放功能=].现在我想在拖放操作完成后显示更改,并让用户再次撤消操作。因此,我为 tableView 实现了自己的 dropEvent() 方法。我还将移动方法设置为 InternalMove.

我在方法内部检查移动确认,然后调用 super(widget.__class__, widget).dropEvent(event)。我希望在这次执行之后,该行被插入到新位置并在旧位置被删除。发生的情况是它在指定位置插入行,但仅在 dropEvent() 完成后才删除旧位置的行。我在函数内部调用 event.accept()event.acceptProposedAction() 并不重要,它总是等到 dropEvent() 完成。

我正在寻找一个信号,告诉我何时执行了拖放操作。我希望 QAbstractItemModelrowsMoved 信号是我想要的,但它不会在 dnd 操作期间发出。然而,信号 rowsInsertedrowsRemoved 被发出。但是 rowsRemoved 信号在 dropEvent() 完成后立即发出。有人知道QTableView在哪里执行目标行的插入、数据的设置和源行的删除吗?

我在 Windows 10 上使用 python3 和 PyQt5。

    def dropEvent_withConfirm(widget, event):
        dropInd = widget.indexAt(event.pos())
        if not dropInd.isValid():
            event.ignore()
            return

        confirmGUI = ConfirmGUI("Drag Element to new position?",
                                "Are you sure you want to drag the element to this position?",
                                True)
        if confirmGUI.getConfirmation():
            super(widget.__class__, widget).dropEvent(event)
            event.accept()
            # Here I want to do something after the finished move, but here the target row was inserted, but the source row is not yet deleted
        else:
            event.ignore()

    self.client.tblView.dropEvent = lambda e: dropEvent_withConfirm(self.client.tblView, e)

我现在解决了这个问题,不依赖 super().dropEvent(),而是自己实现。我找不到在下降完成时发出的合适信号。下面是我更新的代码:

def dropEvent_withConfirm(widget, event):
    dropInd = widget.indexAt(event.pos())
    if not dropInd.isValid():
        event.ignore()
        return

    confirmGUI = ConfirmGUI("Drag Element to new position?",
                            "Are you sure you want to drag the element to this position?",
                            True)
    if confirmGUI.getConfirmation():
        old_row, new_row = getSrcAndDstRow()
        entry            = getDraggedEntry()
        self.myModel.insertRows(new_row)
        self.myModel.setRow(new_row, entry)
        if old_row > new_row:
            self.myModel.removeRows(old_row + 1)
        else:
            self.myModel.removeRows(old_row)
        event.accept()
        # Here I can now do something after the finished move
    else:
        event.ignore()

self.client.tblView.dropEvent = lambda e: dropEvent_withConfirm(self.client.tblView, e)