Drag&Drop: Über ein Objekt hinweg draggen - ohne workaround?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
schnumbl
User
Beiträge: 6
Registriert: Montag 9. Januar 2012, 21:30

Hallo zusammen,

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?

Bild

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()
Antworten