hier ist noch ein Drag&Drop-Issue: Ich möchte ein Objekt über ein anderes hinweg draggen.
Folgender Code funktioniert, allerdings nur mit einem häßlichen work around.
Wie kann ich das schöner programmieren?

Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore
from PyQt4.QtCore import *
from PyQt4 import QtGui
from PyQt4 import QtSvg
class dragdrop_childtarget(QtGui.QFrame):
def __init__(self, ParentWidget, SvgString=""):
super(dragdrop_childtarget, self).__init__(ParentWidget)
self.xpx = 200
self.ypx = 100
self.widthpx = 200
self.heightpx = 300
self.setAcceptDrops(True)
self.setStyleSheet("color:red")
self.setFrameStyle(1)
self.resize(self.widthpx,self.heightpx)
self.move(self.xpx,self.ypx)
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
drag.start(QtCore.Qt.MoveAction)
def dragEnterEvent(self, e):
if e.source() != self:
e.accept()
print "child_target_dragEnter"
else:
e.ignore()
print "child_target_dragEnterIgnore"
def dropEvent(self, e):
if e.source() != self:
print e.pos()
if e.pos().x() > 0 and e.pos().x()< self.widthpx:
if e.pos().y() > 0 and e.pos().y() < self.heightpx:
position = e.pos() + self.pos()
e.source().move(position)
e.setDropAction(QtCore.Qt.MoveAction)
e.accept()
print "child_target_drop"
else:
e.ignore
print "child_target_dropIgnore"
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!!!!!!!!!work around!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
corrected_position = e.pos()
corrected_position.setX(e.pos().x()-self.xpx)
corrected_position.setY(e.pos().y()-2*self.ypx)
self.parent().dropEvent(e,corrected_position)
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
else:
e.ignore()
print "child_target_dropIgnore"
def dragLeaveEvent(self, e):
e.accept()
print "child_target_dragLeave"
class dragdrop_source(QtGui.QFrame):
def __init__(self, ParentWidget, SvgString=""):
super(dragdrop_source, self).__init__(ParentWidget)
self.setAcceptDrops(True)
self.setStyleSheet("color:blue")
self.setFrameStyle(1)
self.resize(40,40)
self.move(150,300)
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
drag.start(QtCore.Qt.MoveAction)
def dragEnterEvent(self, e):
if e.source() != self:
e.accept()
print "source_dragEnter"
else:
e.ignore()
print "source_dragEnterIgnore"
def dragMoveEvent(self, e):
if e.source() != self:
e.accept()
print "source_dragMove"
else:
e.ignore()
print "source_dragMoveIgnore"
def dropEvent(self, e):
if e.source() != self:
e.accept()
print "source_drop"
else:
e.ignore()
print "source_dropIgnore"
def dragLeaveEvent(self, e):
e.accept()
print "source_dragLeave"
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def dragEnterEvent(self, e):
e.accept()
print "panelDragEnter"
#!!!!!!!!!!!!!!!!workaround!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
def dropEvent(self, e, corrected_position = 1e99):
if corrected_position == 1e99:
position = e.pos()
else:
position = corrected_position
print position
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
e.source().move(position)
e.setDropAction(QtCore.Qt.MoveAction)
e.accept()
print "panelDrop"
def initUI(self):
self.setGeometry(200, 200, 800, 800)
self.setAcceptDrops(True)
self.targetObject = dragdrop_childtarget(self)
self.targetObject2 = dragdrop_childtarget(self)
self.targetObject2.move(500,100)
self.sourceObject = dragdrop_source(self)
#Set BackgroundColor
colorstr = 'white'
widget = self
pal = QtGui.QPalette(widget.palette())
pal.setColor(QtGui.QPalette.Background, QtGui.QColor(colorstr))
widget.setPalette(pal)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
#app.setOverrideCursor()
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()