title: PySide2: How to keep QTreeWidgetItem widgets?
body: <p>I have a problem with my custom QTreeWidget losing the associated widgets for each QTreeWidgetItem when it gets dragged and dropped.  I understand that this is due to the item being destroyed and re-created at it's new position, and that it has something to do with the QMimeType, I believe?  But I'm not sure how to work around this to get it to work and preserve/re-create these widgets?  Could I possibly un-parent &amp; reparent them, somehow?  The examples I've been able to find have largely been in QT, which I can read, but I'm not really sure how to implement a solution in PySide2/PyQt.  Would anybody be able to give me any pointers?</p>
  <p>My code is written for Maya, but hopefully it should be able to work outside of Maya as well.  (The custom dropEvent is needed due to a Maya/Mac bug that causes drag and drop actions to completely remove the item on drop.)  You can see that item5 has been re-ordered, but lost it's associated button.</p>
  <p><a href="https://i.stack.imgur.com/FCM2t.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FCM2t.png" alt="QTreeWidget loses QPushButton" /></a></p>
  <pre><code>import sys
  from PySide2 import QtCore, QtWidgets
  
  
  def main():
      try:
          app = QtWidgets.QApplication(sys.argv)
          ui = TreeUI()
          ui.show()
          app.exec_()
      except RuntimeError:
          from maya import OpenMayaUI as omui
          try:
              import shiboken2 as shiboken
          except ImportError:
              import shiboken
          pointer = omui.MQtUtil.mainWindow()
          win = shiboken.wrapInstance(long(pointer), QtWidgets.QWidget)
          ui = TreeUI(parent=win)
          ui.show()
  
  
  class Tree(QtWidgets.QTreeWidget):
  
      def __init__(self, parent=None):
          super(Tree, self).__init__(parent)
          self.setHeaderLabels(('name', 'widget'))
          self.setSelectionMode(self.SingleSelection)
          self.setDragEnabled(True)
          self.setDropIndicatorShown(True)
          self.setDragDropMode(self.InternalMove)
          self.reparented_widgets = {}
  
      def dropEvent(self, event):
          index = self.indexAt(event.pos())
          parent = index.parent()
          self.model().dropMimeData(
              event.mimeData(),
              event.dropAction(),
              index.row(),
              index.column(),
              parent
          )
          event.accept()
  
  
  class TreeUI(QtWidgets.QMainWindow):
  
      def __init__(self, parent=None):
          super(TreeUI, self).__init__(parent)
          widget = QtWidgets.QWidget(self)
          self.setCentralWidget(widget)
          tree = Tree()
          for x in range(0, 6):
              item = QtWidgets.QTreeWidgetItem(tree, ('item{}'.format(x), None))
              item.setFlags(item.flags() &amp; ~QtCore.Qt.ItemIsDropEnabled)
              button = QtWidgets.QPushButton('Button{}'.format(x))
              tree.setItemWidget(item, 1, button)
          layout = QtWidgets.QVBoxLayout(widget)
          layout.addWidget(tree)
  
  
  main()
  
  </code></pre>
  <p>UPDATE #1:
  I'm able to store the widgets for the QTreeWidgetItem within the startDrag function, while removing them from the item.  But then, when I go to add them back to the new QTreeWidgetItem, the application crashes, unfortunately...</p>
  <pre><code>    def startDrag(self, actions):
          column_count = self.columnCount()
          items = self.selectedItems()
          for item in items:
              for x in range(column_count):
                  widget = self.itemWidget(item, x)
                  if widget:
                      self.removeItemWidget(item, x)
                      self.reparent_widgets[x] = widget
          super(Tree, self).startDrag(actions)
  
      def dropEvent(self, event):
          # Fix Mac/Maya drag and drop bug
          index = self.indexAt(event.pos())
          parent = index.parent()
          self.model().dropMimeData(
              event.mimeData(),
              event.dropAction(),
              index.row(),
              index.column(),
              parent
          )
          event.accept()
          # Re-create widget(s)
          pos = event.pos()
          item = self.itemAt(pos)
          for x in self.reparent_widgets.keys():
              self.setItemWidget(item, x, self.reparent_widgets[x])
  
  </code></pre>