This link is what got me started in understanding how QT works with drag and drop. I will post a link to the file in my github account that will use the results of this tutorial (although it is subject to change over time), but with code samples in-page.
http://rowinggolfer.blogspot.ca/2010/04/pyqt4-modelview-drag-drop-example.html
Here is my github source file with drag and drop classes in them:
https://github.com/NucleaPeon/QTCIDE/blob/master/src/view/main/widget.py
Note the following sections:
class Droppable(QtGui.QLabel):
def __init__(self):
super(Droppable, self).__init__()
self.mime = QtCore.QMimeData()
# ... more
def mousePressEvent(self, event):
mime = QtCore.QMimeData()
mime.setText(self.mime.text())
hotSpot = event.pos()
mime.setData("application/x-hotspot", str(hotSpot.x()))
# Create a pixmap of size of self
pixmap = QtGui.QPixmap(self.size())
self.render(pixmap)
drag = QtGui.QDrag(self)
drag.setMimeData(mime)
drag.setPixmap(pixmap)
drag.setHotSpot(hotSpot)
dropAction = drag.exec_(QtCore.Qt.CopyAction|QtCore.Qt.MoveAction, QtCore.Qt.CopyAction)
Important things to note is that droppable object is a QtGui object, therefore has a visual place in the UI, has methods such as
mousePressEvent
in them.
Another odd thing you may notice, is that __init__ has a variable named
self.mime
, whereas
mousePressEvent
has just
mime
. Through trial and error, I found that the
mousePressEvent
method requires an instantiation *each* time the mouse is pressed, otherwise it fails to work. I set a variable in __init__ so that I only have one copy of the data and don't need to keep setting it (hardcoding == bad) in the method itself; changing the constructor variable will change the behaviour of the entire class easily.
class DropCanvas(QtGui.QGraphicsView):
def __init__(self):
super(DropCanvas, self).__init__()
self.setAcceptDrops(True)
self.scene = model.scene.ProjectScene()
def dropEvent(self, event):
# Here is where you put actions you want when the drop is done
def dragEnterEvent(self, event):
event.accept()
This class is the QtGui droppable object. I have it set to QGraphicsView, but it can be anything, such as a different view or a dock or panel, provided it inherits QWidget (I think).
Personally, I have an object that is set up specifically upon a drop event. The code here won't work with a QGraphicsView, but it used to be a QListView so it did work.
class CanvasItem(QtGui.QStandardItem):
def __init__(self, *args, **kwargs):
super(CanvasItem, self).__init__(*args)
self.setEditable(False)
The item inherits a standard item and disables editing of itself.
Put all of the classes together and you can drag and drop!