Drag and Drop in PyQt
10:54am on Jan 14, 2011
So you want to be able to drag items out of a QListView? The docs suck on this. Here's how simple it actually is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class MyListView(QtGui.QListView): def __init__(self, parent=None): super(MyListView, self).__init__(parent) # enable dragging self.setDragEnabled(True) # I'm only interested in drag, not drop, so I disable drop self.setAcceptDrops(False) self.setDragDropMode(QtGui.QAbstractionItemView.DragOnly) # use this to allow selecting multiple entries self.setSelectionMode(QtGui.QAbstractionItemView.ExtendedSelection) def mouseMoveEvent(self, event): self.dragObject() def dragObject(self): if not self.selectedIndexes(): return drag = QtGui.QDrag(self) data = [] for index in self.selectedIndexes(): if not index.isValid(): continue # this assumes your model has a nodeFromIndex() method - # it's easy to set one up, you'll probably have a custom # model class anyways node = self.model().nodeFromIndex(index) data.append(str(node)) # in this case I'm just making a newline-seperated list # of the data, you could do pretty much anything here md = Qt.QMimeData() md.setData('text/plain', "\n".join(data)) # this is important. Without this, it won't do anything. # you can use different actions like Qt.MoveAction, which # would remove the item from your model, but then your model # has to be more complicated. I'm only interested in copy here. drag.setMimeData(md) dropAction = drag.exec_(Qt.Qt.CopyAction) |
Yup, that's it. There's lots of conflicting docs, some tell you to do complicated things with mousePressEvent(), others are older than modern Qt, others just plain wrong.