[PyQt] Drag & Drop with QTreeWidget

Baz Walter bazwal at ftml.net
Wed Dec 2 23:09:38 GMT 2009


NARCISO, Rui wrote:
>>> and when doing so create the sub-node "Folder1" if it does not exist within 
>>> "campaign" and put the dragged items under "folder1" (and not 
>>> "campaign" where they were dropped). How to do this ? Do I do this 
>>> in a dropEvent? In a dropEventAction ?
>> you could monitor the tree using QTreeView.rowsInserted and then 
>> reparent dropped items as necessary.
> 
> Hi again, 
> 
> I have tried but I am unable from redefining rowsInserted to reparent the items.
> I am having problems combining the information QModelIndex used by rowsInserted and the QAbstractModel automatically set-up behind the scenes by QTreeWidget ....

don't know what you're trying to do, but i had in mind something like this:

import sys
from PyQt4 import QtGui, QtCore

CAMPAIGN_TYPE, FOLDER_TYPE, CALC_TYPE = range(1001, 1004)


class TreeWidget(QtGui.QTreeWidget):
     def __init__(self, parent=None):
         QtGui.QTreeWidget.__init__(self, parent)
         self.header().setHidden(True)
         self.setSelectionMode(self.ExtendedSelection)
         self.setDragDropMode(self.InternalMove)
         self.setDragEnabled(True)
         self.setDropIndicatorShown(True)
         self.invisibleRootItem().setFlags(QtCore.Qt.NoItemFlags)
         parent = TreeWidgetItem(self, CAMPAIGN_TYPE)
         for i in xrange(1, 4):
             TreeWidgetItem(parent, CALC_TYPE)
         TreeWidgetItem(self, CAMPAIGN_TYPE)
         TreeWidgetItem(self, CAMPAIGN_TYPE)

     def rowsInserted(self, parent, start, end):
         QtGui.QTreeWidget.rowsInserted(self, parent, start, end)
         item = self.itemFromIndex(parent)
         if (item is not None and
             item.type() == CAMPAIGN_TYPE and
             item.child(start).type() == CALC_TYPE):
             child = item.takeChild(start)
             if item.folder is None:
                 item.folder = TreeWidgetItem(item, FOLDER_TYPE)
             item.folder.addChild(child)


class TreeWidgetItem(QtGui.QTreeWidgetItem):
     def __init__(self, parent, type):
         QtGui.QTreeWidgetItem.__init__(self, parent, type)
         if type == CALC_TYPE:
             text, flags = 'Calc', ~QtCore.Qt.ItemIsDropEnabled
         else:
             self.setChildIndicatorPolicy(self.ShowIndicator)
             self.setExpanded(True)
             if type == CAMPAIGN_TYPE:
                 text, flags = 'Campaign', ~QtCore.Qt.ItemIsDragEnabled
             elif type == FOLDER_TYPE:
                 text, flags = 'Folder', ~QtCore.Qt.ItemIsDragEnabled
         self.setText(0, text)
         self.setFlags(self.flags() & flags)
         self.folder = None


if __name__ == "__main__":
     app = QtGui.QApplication(sys.argv)
     tree = TreeWidget()
     tree.resize(200, 300)
     tree.move(300, 300)
     tree.show()
     sys.exit(app.exec_())


More information about the PyQt mailing list