[Interest] Reorder QTableView rows via drag and drop

Murphy, Sean smurphy at walbro.com
Tue Jan 19 20:34:50 CET 2016


I’ve got a QTableView that I’d like to be able to reorder the rows via drag n drop. So reading up on how to do it I stumbled across 
    void QHeaderView::setSectionsMovable(bool movable)
which allows the user to grab the header section, reorder the rows in the view, and then I can grab this signal
    void QHeaderView::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
to update my data model accordingly. So I whipped up a little test app, and it almost does what I want, except for a couple things:
- in the real application we aren't using a vertical header. I could probably change what I'm doing right now to replace what is currently my first column of data and put that information on the vertical header instead
- using the header view only allows the user to begin the drag on the header section. Ideally, I'd like the user to be able to start the drag anywhere on the entire row, not just the header (if I even choose to have a header)

As I've kept poking around, it looks like to do what I want I need to override a bunch of functions in the model class (supportedDropActions(), dropMimeData(), flags(), etc.) as well as enable a handful of drag and drop settings on the table view itself. So it goes from a one-liner doing it through the header class, to a lot more code in the view & model class. It doesn't look too hard to do, but before I go down that path, I just wanted to make sure I'm not missing something easier?

So the basic requirements:
- table view selects entire rows (ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows))
- user should be able to reorder rows by starting a drag anywhere on a given row
- dropping the item reorders the rows, and provides me a signal of that action so I can update the underlying data. My application presents the underlying data in a couple different spots/ways, and we want to ensure that all spots are always in the same order. So if the user changes the order in this table, I need to update the other displays as well so I just need to know when this event happens
- I'd love for there to be a nice visually indicator of where the drop is going to happen. As I was playing around with overriding the model drag and drop stuff, the default action appeared to highlight the a cell where the drop was going to happen, which looked a little weird as I was dragging an entire row, but the drop indicator was the border around a single cell
- all drag and drops are internal to the table, I don't need to support dropping anything external onto the table

Sean






More information about the Interest mailing list