I am trying to do drag and drop of rows inside a QTableWidget.
The drag and drop operation itself is working great, but when I click and release the mouse button rapidly on a row , the drop event is never called. Even with the mouse released, the cursor is still in drag mode until I click again.
When I click an release slowly on a row, to select it, the events are: - mousePressEvent - dragEnterEvent - dropEvent
When I click and release rapidly, the events are: - mousePressEvent - mouseReleaseEvent - dragEnterEvent and dropEvent is only called if I click again.
This is probably because the dragEnterEvent (that should never be called, I think) 'hides' the mouseReleaseEvent to the drag operation.
Is there a way to force the end of the drag operation ? or better, to prevent the drag operation to call dragEnterEvent ?
Here is my code:
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()
Thanks a lot