Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-63299

QTableView + InternalMove + SelectRows Drag-and-Drop improvements

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • 5.9.1
    • None
    • Running on Linux/X11, Qt 5.9.1

    Description

      I was implementing a QTableView in which the user would be able to select an entire row and drag it to a new position.  This is pretty trivial using QStandardItemModel/QStandardItem along with QTableView, using attributes like the following (examples are in PyQt, sorry!) -

      tableview.setSelectionBehavior(tableview.SelectRows)
      tableview.setSelectionMode(tableview.SingleSelection)
      tableview.setDragDropMode(tableview.InternalMove)
      tableview.setDragDropOverwriteMode(False)
      model = QStandardItemModel()
      tableview.setModel(model)

      And then for each of the QStandardItem objects being added to the model, making sure to call "setDropEnabled(False)" on each one, so that reordering is the only operation possible.

      All this by itself works pretty well for most cases, but leaves two gaps which I believe should be default behavior when using this combination of InternalMove and SelectRows.  Namely:

      1. It's possible to drag a row into another column, which ends up copying the data (instead of moving), and adds at least one column to the Model.  Basically shifting the row you were dragging off to the right.
      2. Relatedly, while you're in the middle of a drag operation, the between-row DropIndicator will only draw beneath the cell that you're currently hovering over, rather than drawing across the entire row, as would be more intentional.

      Both of those points aren't too difficult to address in code.  For #1, you can inherit QStandardItemModel and override dropMimeData to force the "col" parameter to always be zero.  This will make dropping a row to reorder it always just move the row, as I think the user would expect, regardless of what column is being hovered.

      Fixing #2 requires setting up a QProxyStyle and attaching it to the QTableView, and expanding the geometry of the line to be drawn.  Though I think that this solution wouldn't necessarily work on other global styles, such as OSX...

      IMO there should at least be some booleans which can be set on the QTableView which would set this behavior up without having to resort to subclassing QStandardItemModel and QProxyStyle.  I'm personally of the opinion that given the combination of InternalMove and SelectRows, the behavior I'd like should be the default, but I'd certainly understand if everyone else disagrees. 

      I've attached a small standalone pyqt script which demonstrates the fixes for the two issues I mentioned.  It's basically those two classes "MyModel" and "MyStyle" which I think shouldn't be necessary when setting up a QTableView with InternalMove and SelectRows.

      Let me know if I've been unclear, thanks!

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            richard Richard Moe Gustavsen
            apocalyptech CJ Kucera
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes