Using PySide, I construct a draggable label that works exactly how I want:
class DraggableLabel(QtGui.QLabel):
def __init__(self, txt, parent):
QtGui.QLabel.__init__(self, txt, parent)
self.setStyleSheet("QLabel { background-color: rgb(255, 255, 0)}")
def mouseMoveEvent(self, event):
drag=QtGui.QDrag(self)
dragMimeData=QtCore.QMimeData()
drag.setMimeData(dragMimeData)
drag.exec_(QtCore.Qt.MoveAction)
(Note a full example that uses DraggableLabel
is pasted below). Unfortunately, I do not understand what is going on with QMimeData
, and fear I am going to run into big problems when I use similar code in real-world examples.
In particular, I am worried that my reimplementation of mouseMoveEvent
creates an instance of QMimeData
without any argument passed: QtCore.QMimeData()
. Is this normal? Within more complex widgets will I be OK if I keep doing that within the relevant event handler: will the program automatically create the right type of MIME data for dragging and dropping?
The reason I fear I am missing something is because at the Qt Drag and Drop documentation, it has lines of code like:
mimeData -> setText(commentEdit->toPlainText());
which seems decidedly not like just letting the program take care of things within a reimplementation of an event handler.
Also, the QMimeData Documentation discusses convenience functions to test, get, and set data, but those are for standard data types (e.g., text, urls). I have found no clear way to define such convenience functions for widgets like my draggable QLabel
. Am I missing it? Is there a simple way to find out if I am dragging around a widget of type X?
Edit: I've tried the same code above with much more complicated widgets than QLabels, and it does not work.
Potentially relevant posts:
Dragging a QWidget in QT 5
How to Drag and Drop Custom Widgets?
https://stackoverflow.com/questions/18272650/fill-the-system-clipboard-with-data-of-custom-mime-type
Python object in QMimeData
Important Caveat: if you just want to move a widget in a window, you do not need to invoke esoteric drag-drop mechanisms, but more vanilla event handling. See this: Dragging/Moving a QPushButton in PyQt.
Full working self-contained code example that incorporates the above:
# -*- coding: utf-8 -*-
from PySide import QtGui, QtCore
class LabelDrag(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.initUI()
def initUI(self):
self.lbl=DraggableLabel("Drag me", self)
self.setAcceptDrops(True)
self.setGeometry(40,50,200,200)
self.show()
def dragEnterEvent(self,event):
event.accept()
def dropEvent(self, event):
self.lbl.move(event.pos()) #moves label to position once the movement finishes (dropped)
event.accept()
class DraggableLabel(QtGui.QLabel):
def __init__(self, txt, parent):
QtGui.QLabel.__init__(self, txt, parent)
self.setStyleSheet("QLabel { background-color: rgb(255, 255, 0)}")
def mouseMoveEvent(self, event):
drag=QtGui.QDrag(self)
dragMimeData=QtCore.QMimeData()
drag.setMimeData(dragMimeData)
drag.exec_(QtCore.Qt.MoveAction)
def main():
import sys
qt_app=QtGui.QApplication(sys.argv)
myMover=LabelDrag()
sys.exit(qt_app.exec_())
if __name__=="__main__":
main()
Note I'm posting this at QtCentre as well, will post anything useful from there.