Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Treeview Drag and Drop row with multiple columns issue on root index
QtWS25 Last Chance

Treeview Drag and Drop row with multiple columns issue on root index

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 764 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • alomA Offline
    alomA Offline
    alom
    wrote on last edited by
    #1

    Hi,
    I have a treeview/QStandardItemModel with a dragDropMode set to InternalMove and a selectionBehavoir set to SelectRows. The model has three columns. The expected behavior from the user is to move the three columns in a row as a whole and rearrange the tree hierarchy as needed.

    Everything works as expected when dragging and dropping a row from column 0 on top of anther column 0. I've set the items flags on the column 1/2 items not to accept drops. The issue comes when dragging from a row to the root Item on the model and dropping in on column 1 or 2. This causes the model to create extra columns and places column 0 data in one the incorrect columns.

    How can I treat the selected row and all its items drop to always drop on column 0, when dropping on the root index?
    Do I have to re implement one of the dragDrop functions on the QStandardItemModel?

    Thanks

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What version of Qt are you using ?
      On what OS ?
      Can you provide a minimal compilable example that shows that behaviour ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • alomA Offline
        alomA Offline
        alom
        wrote on last edited by alom
        #3

        Hi SGaist,
        Sure, I'm on Windows 10 pro, Pyside2 v5.13.2, py3.7.6
        I was hoping to post here without python code to get more eyes on this issue than in python forum, I'm sure some of the c++ guys have ran into this before.

        So you can drop a "child" index under any parent and root index. The parents can be drop in each other. The issue is when dropping a child or parent on the root index on column 1 or 2.

        
        import sys
        from PySide2 import QtWidgets, QtGui
        from PySide2.QtCore import Qt
        
        
        class SnippetTreeView(QtWidgets.QTreeView):
        
            def __init__(self, parent=None):
                super(SnippetTreeView, self).__init__(parent)
                self.setContextMenuPolicy(Qt.CustomContextMenu)
                self.setDragEnabled(False)
                self.setDragDropOverwriteMode(False)
                self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
                self.setAlternatingRowColors(True)
                self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
                # self.setSortingEnabled(True)
                self.header().setStretchLastSection(True)
                self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        
        
        def create_tag_color_items():
            item_tag = QtGui.QStandardItem('tag')
            item_tag.setDropEnabled(False)
            item_color = QtGui.QStandardItem('color')
            item_color.setDropEnabled(False)
            return item_tag, item_color
        
        
        def add_items(model):
            headers = [
                'Name',
                'Tag',
                'Color',
            ]
            names = [
                'child-0',
                'child-1',
            ]
        
            model.setHorizontalHeaderLabels(headers)
            model.setColumnCount(len(headers))
        
            for num in range(2):
                parent_item = QtGui.QStandardItem('parent-yesDrops-' + str(num))
                parent_item.setDropEnabled(True)
                item_tag, item_color = create_tag_color_items()
        
                for name in names:
                    child_item = QtGui.QStandardItem(name + '-noDrops' )
                    child_item.setDropEnabled(False)
                    ch_item_tag, ch_item_color = create_tag_color_items()
                    parent_item.appendRow([child_item, ch_item_tag, ch_item_color])
        
                model.appendRow([parent_item, item_tag, item_color])
        
        
        if __name__ == '__main__':
            app = QtWidgets.QApplication(sys.argv)
            tree = SnippetTreeView()
            model = QtGui.QStandardItemModel()
            add_items(model)
            tree.setModel(model)
            tree.show()
            rec = app.exec_()
            sys.exit(rec)
        
        1 Reply Last reply
        0
        • alomA Offline
          alomA Offline
          alom
          wrote on last edited by alom
          #4

          I did see the canDropMineData function in the model.
          How correct/safe is this approach? Am I missing any important handing of other information floating around when doing this?

          I just return a false bool on any column greater than 0.

          class DropModel(QtGui.QStandardItemModel):
              def __init__(self, parent=None):
                  super(DropModel, self).__init__(parent)
          
              def canDropMimeData(self, data, action, row, column, parent):
                  if column > 0:
                      return False
                  return QtGui.QStandardItemModel().canDropMimeData(data, action, row, column, parent)
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            What about subclassing QStandardItemModel like that:

            class MyModel(QtGui.QStandardItemModel):
                def dropMimeData(self, data, action, row, column, parent):
                    return super().dropMimeData(data, action, row, 0, parent)
            

            ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • alomA Offline
              alomA Offline
              alom
              wrote on last edited by alom
              #6

              Oh very nice!
              I think that was what I was looking for. Feels much cleaner.
              Thanks @SGaist !

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved