i can’t find an example on dragging (and dropping) multiple elements with Qt/PyQt;
In my case i need to drag elements from this QTableView:
class DragTable(QTableView):
def __init__(self, parent = None):
super(DragTable, self).__init__(parent)
self.setDragEnabled(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
event.setDropAction(Qt.MoveAction)
event.accept()
else:
event.ignore()
def startDrag(self, event):
print type(event)
index = self.indexAt(event.pos())
if not index.isValid():
return
selected = index.row()
bstream = cPickle.dumps(selected)
mimeData = QMimeData()
mimeData.setData("application/pubmedrecord", bstream)
drag = QDrag(self)
drag.setMimeData(mimeData)
pixmap = QPixmap(":/drag.png")
drag.setHotSpot(QPoint(pixmap.width()/3, pixmap.height()/3))
drag.setPixmap(pixmap)
result = drag.start(Qt.MoveAction)
def mouseMoveEvent(self, event):
self.startDrag(event)
To this QLabel (My dropzone):
class TagLabel(QLabel):
def __init__(self, text, color, parent = None):
super(TagLabel, self).__init__(parent)
self.tagColor = color
self.setText(text)
self.setStyleSheet("QLabel { background-color: %s; font-size: 14pt; }" % self.tagColor)
self.defaultStyle = self.styleSheet()
self.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
self.set_bg(True)
event.accept()
else:
event.reject()
def dragLeaveEvent(self, event):
self.set_bg(False)
event.accept()
def dropEvent(self, event):
self.set_bg(False)
data = event.mimeData()
bstream = data.retrieveData("application/pubmedrecord", QVariant.ByteArray)
selected = pickle.loads(bstream.toByteArray())
event.accept()
self.emit(SIGNAL("dropAccepted(PyQt_PyObject)"), (selected, str(self.text()), str(self.tagColor)))
def set_bg(self, active = False):
if active:
style = "QLabel {background: yellow; font-size: 14pt;}"
self.setStyleSheet(style)
else:
self.setStyleSheet(self.defaultStyle)
Any tips? Thank you!
Here’s a full working example:
Why are you using
cPickleas well aspickle?You probably want to set the selection behavior here, because I’m assuming row-based data presentation. You may of course change that.
Your code assumes only one index here, based on the event position. For a
QTableView, this is unnecessary, as it already handles the mouse click itself. Instead, it’s better to depend on Qt to provide you with the information that you actually need, as always. Here, I’ve chose to useselectedIndexes().Indices is now a list of
QModelIndexinstances, that I chose to convert to a set of row numbers. It’s also possible to convert these to a list ofQPersistentModelIndexes, depending on your needs.One thing that may surprise you here, is that indices contains indexes for all cells in the table, not all rows, regardless of the selection behavior. That’s why I chose to use a
setinstead of alist.I left the rest untouched, assuming that you know what you’re doing there.
Unless you are interfacing with C++-code with this signal, it’s not necessary to add a signal argument here, you may also use
dropAcceptedwithout parentheses and PyQt4 will do the right thing.