PySide how to get a target on dropEvent

Question:

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

Asked By: ChrilleMZ

||

Answers:

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()
Answered By: ChrilleMZ

In PySide2 you can get target event by this.

from PySide2 import QtWidgets
from PySide2 import QtCore

class MyTreeWidget(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
    super(MyTreeWidget, self).__init__(parent)
    self.setAcceptDrops(True)
    self.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
    self.setDefaultDropAction(QtCore.Qt.CopyAction)
    self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)


def dropEvent(self, event):
    item = self.itemAt(event.pos())
    print(item.text(0))
Answered By: Rajiv Sharma
def dropEvent(self, event):
    destination = self.centralWidget().childAt(event.pos()).objectName()
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.