PDA

View Full Version : Drag and Drop inside QTableView with QStandardItemModel



gig-raf
25th January 2016, 21:48
Dear ALl,

I have a question that I am hoping someone in the Forum can help me with.

I have QtableView, using the QStandardItemModel. I need to be able to sort/arrange the content of the model by dragging and dropping its items. Is this possible with the QStandarItemModel and QTableView?
so in short I would be able to drag item2 and drop it on top of item1 - result should be that item1 and item2 swap place. I do not want to drop between, only on top of other items. No new lines should be created....

I am configuring the QTableView the following way.



...
tableView->setContextMenuPolicy(Qt::CustomContextMenu);
tableView->setSelectionBehavior(QAbstractItemView::SelectItem s);
tableView->setAlternatingRowColors(true);
tableView->setDropIndicatorShown(true);
tableView->setDragDropOverwriteMode(false);
tableView->setDragEnabled(true);
tableView->setDragDropMode(QAbstractItemView::InternalMove);
tableView->setDragDropMode(QAbstractItemView::DragDrop);
...


BUt if I drag item1 and drop on item2 nothing happens. If I drag item1 and drop it between item2 and item3. item1 is appended to the model at the very bottom.??

Any help is most appreciated.

d_stranz
25th January 2016, 22:05
tableView->setDragDropMode(QAbstractItemView:: InternalMove);
tableView->setDragDropMode(QAbstractItemView:: DragDrop);

The second line cancels the first; it isn't an "OR" operation.

Have you read this? (http://doc.qt.io/qt-5/model-view-programming.html#using-drag-and-drop-with-item-views)

gig-raf
25th January 2016, 22:40
Thanks for taking the time to answer me. True with the bottom two lines. I removed the bottom one, and left solely the InternalMove.

I can now drop item1 on item2, but then item1 is cleared (removed) and item2 remains unchanged. What I want is that item1 and item2 just swap place.

I will have a read at you link and see if I can progress with this tomorrow.

cheers!

gig-raf
26th January 2016, 14:00
Okay managed to get it working with QTableView and QStandardItems.

here for those who might have similar need:

The key for the success was setting the item.setFlags as below and the three drag options at the bottom.




model = new QStandardItemModel(0,1,this);

// Attach the model to the view
ui->downloadView->setModel(model);
QStandardItem* itm = new QStandardItem();
QList<QStandardItem*> data;
itm = new QStandardItem("Breitner");
itm->setFlags(itm->flags() & ~(Qt::ItemIsDropEnabled));
data.append(itm);
model->appendRow(data);
data.clear();
itm = new QStandardItem("Laudrup");
itm->setFlags(itm->flags() & ~(Qt::ItemIsDropEnabled));
data.append(itm);
model->appendRow(data);
data.clear();
itm = new QStandardItem("Platini");
itm->setFlags(itm->flags() & ~(Qt::ItemIsDropEnabled));
data.append(itm);
model->appendRow(data);
data.clear();
itm = new QStandardItem("Paolo Rossi");
itm->setFlags(itm->flags() & ~(Qt::ItemIsDropEnabled));
data.append(itm);
model->appendRow(data);
data.clear();
itm = new QStandardItem("Lineker");
itm->setFlags(itm->flags() & ~(Qt::ItemIsDropEnabled));
data.append(itm);
model->appendRow(data);
data.clear();

ui->downloadView->setDragDropOverwriteMode(false);
ui->downloadView->setDragEnabled(true);
ui->downloadView->setDragDropMode(QAbstractItemView::InternalMove);

d_stranz
27th January 2016, 03:22
QStandardItem* itm = new QStandardItem();
QList<QStandardItem*> data;
itm = new QStandardItem("Breitner");


The first line above is a memory leak because you create the item, do nothing with it, and then overwrite the pointer in the third line.

Thanks for sharing your solution.