[Maya] PySide QTreeWidget drag and drop objects from outliner

coding
qt
maya
python

#1

Been struggling past few days to allow drag and dropping from Maya’s Outliner to a custom QTreeWidget.

Current code:

class HierarchyWidget(QTreeWidget):
    """ Subclass of QTreeWidget to support Drag and Drop in Maya. """

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

        self.setDragDropMode(self.DragDrop)
        self.setDefaultDropAction(Qt.MoveAction)
        self.setDropIndicatorShown(True)
        self.setDragEnabled(True)

        # self.setAcceptDrops(True)
        # self.setDragDropOverwriteMode(True)

        rootItem = self.invisibleRootItem()
        rootItem.setFlags(Qt.ItemIsDropEnabled)

        viewport = self.viewport()
        viewport.setAcceptDrops(True)

        print(self.mimeTypes())

    def mimeTypes(self):
        return 'application/x-maya-data'

    def dropEvent(self, event):
        print("Dropped!")

    def supportedDropActions(self):
        """ """
        return Qt.MoveAction | Qt.CopyAction

I add this widget into a QWidget with QGridLayout (if that matters)

So far think I’ve iterated through all possible Drag and Drop Modes, tried setting an invisible root item for the Tree - rewrote the code on: https://kylemr.blogspot.se/2013/04/pyqt-drag-and-drop-outliner-like.html to fit PySide but seems that code couldn’t handle drag and drop either.

Using Maya 2018, PySide.version = 2.0.0~alpha0


#2

Managed to solve it,

class HierarchyWidget(QTreeWidget):
    """ Subclass of QTreeWidget to support Drag and Drop in Maya. """

    def __init__(self, *args, **kwargs):
        super(HierarchyWidget, self).__init__(*args, **kwargs)

        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        """ Reimplementing event to accept plain text, """
        if event.mimeData().hasFormat('text/plain'):
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        """ Reimplementing event to accept plain text, """
        if event.mimeData().hasFormat('text/plain'):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        """ """
        print("Dropped!")

Did a check to see the mimetype formats and data for each when I dragged and dropped into a QLineEdit, saw both the ‘application/x-maya-data’ and ‘text/plain’ - where text/plain data was the long name of the node dropped.