Search code examples
pythondrag-and-droppyside

PySide how to get a target on dropEvent


I trying to make a user friendly drag and drop UI where I have to areas (QTreeWidgets) where you can drag and drop items. Some items can't be dragged at all and some can be dragged but only onto certain items.

I have managed to set items to not be dragged by storing a drag True or False variable on item and check when entering the dragEnterEvent like this

class SpecialTreeWidget(QtGui.QTreeWidget):

    def __init__(self, parent=None):
        super(SpecialTreeWidget, self).__init__(parent)

    def dragEnterEvent(self, event):
        super(SpecialTreeWidget, self).dragEnterEvent(event)
        mSenderItems = event.source().selectedItems()
        for item in mSenderItems:
            if not item.scriptMenuData["drag"]:
                event.ignore()
                break
        else:
            event.accept()

When I drag a none movable icon appears if the items has the scriptMenuData["drag"] set to False.

The problem now is to do the same thing but when I trying to drop an item on certain items. My initial though was to do like this in the same class

def dragMoveEvent(self, event):
        super(SpecialTreeWidget, self).dragMoveEvent(event)
        mTargetItem = event.target()
        if mTargetItem.scriptMenuData["drop"]:
            event.accept()
        else:
            event.ignore()

But there is no event.target() and I can't find any way to get the target except for the dropMimeData method but that's to late, I want the "you can't drop here" icon when moving over the item, not when it's been dropped.

Any suggestions on how to get the target, is there a way to get a widget that is under the mouse maybe or maybe there is another event/method/signal that I can use?

Thanks in advance.

/Christian M


Solution

  • So I manage to find a solution, you can catch which item that is under a point with QTreeWidget.itemAt() The code looks like this

    def dragMoveEvent(self, event):
            super(SpecialTreeWidget, self).dragMoveEvent(event)
            mDropItem = self.itemAt(event.pos())
            if mDropItem:
                if mDropItem.scriptMenuData["drop"]:
                    event.accept()
                else:
                    event.ignore()
            else:
                event.accept()