PyQt4拖放在dragEnter之前接收mouseReleaseEvent

问题描述 投票:0回答:1

我正在尝试在QTableWidget内拖放行。

拖放操作本身运行良好,但是当我单击并连续释放鼠标按钮rapidly时,永远不会调用drop事件。即使释放了鼠标,光标仍处于拖动模式,直到再次单击。

当我连续缓慢单击发行版以选择它时,事件是:-mousePressEvent-dragEnterEvent-dropEvent

当我单击并快速释放时,事件为:-mousePressEvent-mouseReleaseEvent-dragEnterEvent仅在再次单击时才会调用dropEvent。

这可能是因为dragEnterEvent(我认为永远不应该调用)将mouseReleaseEvent隐藏到拖动操作中。

是否有强制结束拖动操作的方法?或更好,以防止拖动操作调用dragEnterEvent?

这是我的代码:

class DragDropTableWidget(QTableWidget):

    moveRow = pyqtSignal(int, int)

    def __init__(self, parent):
        super(QTableWidget, self).__init__(parent)

        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.viewport().setAcceptDrops(True)
        self.setDragDropOverwriteMode(False)
        self.setDropIndicatorShown(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setDragDropMode(QAbstractItemView.InternalMove)

        self.released = False

    def mousePressEvent(self, event):
        print('Mouse Press')
        self.released = False

        index = self.indexAt(event.pos())
        if not index.isValid():
            return

        row = index.row()
        self.selectRow(row)

        mime_data = QMimeData()
        mime_data.setData("index", str(row))

        drag = QDrag(self)
        drag.setMimeData(mime_data)
        drag.start(Qt.MoveAction)

    def dragEnterEvent(self, e):
        print('Drag Enter')
        if self.released:
            # todo: cancel drag and drop
            pass
        else:
            e.accept()

    def dragMoveEvent(self, e):
        e.accept()

    def mouseReleaseEvent(self, e):
        print('Mouse release')
        self.released = True

    def dropEvent(self, event):
        print('Drop event')
        if event.source() == self:
            index = self.indexAt(event.pos())
            if not index.isValid():
                event.accept()
                return
            start_index = int(event.mimeData().data("index"))
            if start_index != index.row():
                print ("dropEvent called from row {} on row {}".format(start_index, index.row()))
                self.moveRow.emit(start_index, index.row())

            event.accept()

非常感谢

pyqt drag-and-drop qtablewidget
1个回答
0
投票

我最终得出结论,从我的观点出发,最简单的解决方案是通过确保没有释放鼠标来保护drag.start。我确信有更好的解决方案,但是我找不到它,经过大量搜索和误导之后,这是我的工作类(在QT <4.3和Linux上):

from PyQt4.QtGui import QTableWidget, QAbstractItemView, QDrag
from PyQt4.QtCore import QMimeData, Qt, pyqtSignal


class DragDropTableWidget(QTableWidget):
    moveRow = pyqtSignal(int, int)

def __init__(self, parent):
    super(QTableWidget, self).__init__(parent)

    self.setDragEnabled(True)
    self.setAcceptDrops(True)
    self.viewport().setAcceptDrops(True)
    self.setDragDropOverwriteMode(False)
    self.setDropIndicatorShown(True)
    self.setSelectionMode(QAbstractItemView.SingleSelection)
    self.setSelectionBehavior(QAbstractItemView.SelectRows)
    self.setDragDropMode(QAbstractItemView.InternalMove)

    self.released = False

def mousePressEvent(self, event):
    self.released = False

    index = self.indexAt(event.pos())
    if not index.isValid():
        return

    row = index.row()
    self.selectRow(row)

    mime_data = QMimeData()
    mime_data.setData("index", str(row))

    drag = QDrag(self)
    drag.setMimeData(mime_data)

    if not self.released:
        # this will prevent the case where the click release is very quick and we release before the drag/drop start
        drag.start(Qt.MoveAction)

def dragEnterEvent(self, e):
    e.accept()

def dragMoveEvent(self, e):
    e.accept()

def mouseReleaseEvent(self, e):
    self.released = True

def dropEvent(self, event):
    if event.source() == self:
        index = self.indexAt(event.pos())
        if not index.isValid():
            event.accept()
            return
        start_index = int(event.mimeData().data("index"))
        if start_index != index.row():
            self.moveRow.emit(start_index, index.row())

        event.accept()
© www.soinside.com 2019 - 2024. All rights reserved.