Tags

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.

Tags