Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to accept or refuse a drop in a QTreeWidget depending on where something is dropped in it in PySide 1.0.9?



  • Hey,

    I have a simple QTreeWidget and I try to find out where something is dropped so I can either refuse the drop or accept it (in Python 2.6.5, PySide 1.0.9, Qt version 4.7.2).

    I have reimplemented dropEvent(). With self.itemAt(event.pos()) I can get the item on which something will be dropped, but how can I find out if something is dropped on an item or above/below it? QAbstractItemView has the function dropIndicatorPosition() (according to the Documentation), but it's not accessible in Python 2.6.5, PySide 1.0.9, Qt version 4.7.2.

    I have no problem with the code below in Python 2.7.17, PySide 1.2.4., Qt version 4.8.7, but in Python 2.6.5, PySide 1.0.9, Qt version 4.7.2 I get the following: AttributeError: 'SimpleTreeWidget' object has no attribute 'dropIndicatorPosition'

    Is there any way to get the dropIndicatorPosition in Python 2.6.5, PySide 1.0.9, Qt version 4.7.2 inside dropEvent() of a QTreeWidget or is there any other way to get that information?

    import sys
    from PySide import QtGui
    
    class SimpleTreeWidget(QtGui.QTreeWidget):
        def __init__(self, parent = None):
            QtGui.QTreeWidget.__init__(self, parent)
            self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
            self.setItemsExpandable(True)
            self.setDragEnabled(True)
            self.setDropIndicatorShown(True)
            self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
            self.setColumnCount(2)
            self.setHeaderLabels(("A", "B"))
    
        def dropEvent(self, event):
            itemToDropIn = self.itemAt(event.pos())
            dropInidcatorPosition = self.dropIndicatorPosition()
    
            print dropInidcatorPosition
    
            super(SimpleTreeWidget, self).dropEvent(event)
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
    
        tree = SimpleTreeWidget()
    
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["A"]))
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["B"]))
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["C"]))
    
        tree.show()
    
        sys.exit(app.exec_())
    

    I also tried to reimplement dropMimeData(). With that I can get the parent and index to find out where something is dropped and it also works in Python 2.6.5, PySide 1.0.9, Qt version 4.7.2. See code below. But for that I have to change the line self.setDragDropMode(QtGui.QAbstractItemView.InternalMove) to self.setDragDropMode(QtGui.QAbstractItemView.DragDrop). dropMimeData() doesn't seem to get called when the QTreeWidget is set to QtGui.QAbstractItemView.InternalMove. But I'd like to keep it as InternalMove.

    Also the items are copied when they are dropped, despite having set the action in dropMimeData() to QtCore.Qt.DropAction.MoveAction.

    import sys
    from PySide import QtGui, QtCore
    
    class SimpleTreeWidget(QtGui.QTreeWidget):
        def __init__(self, parent = None):
            QtGui.QTreeWidget.__init__(self, parent)
            self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
            self.setItemsExpandable(True)
            self.setDragEnabled(True)
            self.setDropIndicatorShown(True)
            self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
            self.setColumnCount(2)
            self.setHeaderLabels(("A", "B"))
    
        def dropMimeData(self, parent, index, mimeData, action):
            if parent:
                print parent.text(0)
            print index
            print action
    
            return super(SimpleTreeWidget, self).dropMimeData(parent, index, mimeData, QtCore.Qt.DropAction.MoveAction)
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
    
        tree = SimpleTreeWidget()
    
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["A"]))
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["B"]))
        tree.addTopLevelItem(QtGui.QTreeWidgetItem(["C"]))
    
        tree.show()
    
        sys.exit(app.exec_())
    

    I'm honestly a little lost and would be thankful for some help.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    It might just be an issue with the generated bindings of that version.

    In any case, you should seriously consider updating. You are using a software stack that is way more than outdated.



  • Hey,

    thanks for the reply.

    Yes, you are right, it's quite outdated. However I'm writing a Plug-in for a software called Nuke. That Plug-in needs to work in older versions too. The newest version is Nuke 12. But the Plug-in has to also work with Nuke 7. Nuke 7 however comes with Python 2.6.5, PySide 1.0.9, Qt version 4.7.2. So I don't really have much of a choice. That's why I'm asking, if there is any other way to get the information where something will be dropped.

    Maybe someone who is more experienced than me has a better idea, but the only idea I currently have, if the above is not possible, is to accept the drop and if it's invalid to move the entire subtree back to it's previous position. But that's a solution that I'd like to avoid.

    In any case thanks for the reply and if someone has a better idea than me I'd really like to hear it.


Log in to reply