PDA

View Full Version : QTreeWidget: Drag and Drop



laugusti
11th June 2010, 15:37
Hi everybody,

I am currently trying to enable the Drag n Drop functionnality for a QTreeWidget.
I am able to drag and drop items but I am clueless on two problems:

I just want to move items around but it seems that the item is copied when I drag n drop. However the action is a Qt::MoveAction when I look at it in QTreeWidget::dropMimeData().
I am able to drop an item onto another item which I don't want. I use a custom QTreeWidgetItem without the flag Qt::ItemIsDropEnabled. It works for the first drag n drop action, but not anymore on the 2nd action.


Here is my code:


QMyTreeItem::QMyTreeItem(QTreeWidgetItem* parent, const boost::shared_ptr<Filter>& filter) : QTreeWidgetItem(parent), m_filter(filter) {

setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
setText(QFilterTree::UNIQUE_COLUMN_INDEX, filter->getName().toStdString().c_str());
}


QMyTree::QMyTree(QWidget *parent) : QTreeWidget(parent) {
setColumnCount(1);
header()->hide();
setSelectionBehavior(QAbstractItemView::SelectRows ); // Only rows are selectable
setSelectionMode(QAbstractItemView::SingleSelectio n); // Define selection behavior
setDragEnabled(true);
viewport()->setAcceptDrops(true);
setDropIndicatorShown(true);
setDragDropMode(QAbstractItemView::InternalMove);
}


void QMyTree::refresh() {
FilterList filters = DsmEditorWorkbench::getInstance()->getDsmProjectManager()->getActiveProject()->getEditedDsm()->getFilters();
for (FilterList::const_iterator it = filters.begin(); it != filters.end() ; it++) {
FilterShPtr filter = *it;
QMyTreeItem* treeItem = new QMyTreeItem(this, filter);
addTopLevelItem(treeItem);
}

for (int i=0; i <topLevelItemCount(); i++) {
QTreeWidgetItem* item = topLevelItem(i);
if (item) {
qDebug() << "QMyTree::refresh() => item present at index: " << i;

if (dynamic_cast <QMyTreeItem*> (item)) {
qDebug() << "QMyTree::refresh() => It's a QMyTreeItem";
}
}
}
}


void QMyTree::dropEvent(QDropEvent* event) {
qDebug() << "QMyTree::dropEvent()";
QAbstractItemView::dropEvent(event);

// Look over top level items
for (int i=0; i <topLevelItemCount(); i++) {
QTreeWidgetItem* item = topLevelItem(i);
if (item) {
qDebug() << "QMyTree::dropEvent() => item present at index: " << i;

if (dynamic_cast <QMyTreeItem*> (item)) {
qDebug() << "QMyTree::dropEvent() => It's a QMyTreeItem";
}
}
}
}

In the example below, I'll have 2 items:
|-item1
|
|-item2

Here is the messages I get after the refresh() method when opening the application:
QMyTree::refresh()
QMyTree::refresh() => item present at index: 0
QMyTree::refresh() => It's a QMyTreeItem
QMyTree::refresh() => item present at index: 1
QMyTree::refresh() => It's a QMyTreeItem

1rst drag n drop => I put item1 below item2:
|-item2
|
|-item1

Messages:
QMyTree::dropEvent()
QMyTree::dropEvent() => item present at index: 0
QMyTree::dropEvent() => It's a QMyTreeItem
QMyTree::dropEvent() => item present at index: 1
QMyTree::dropEvent() => It's a QMyTreeItem
QMyTree::dropEvent() => item present at index: 2

2nd drag n drop => I put item2 below item1 (initial order):
|-item1
|
|-item2

Messages:
QMyTree::dropEvent()
QMyTree::dropEvent() => item present at index: 0
QMyTree::dropEvent() => It's a QMyTreeItem
QMyTree::dropEvent() => item present at index: 1
QMyTree::dropEvent() => item present at index: 2


It looks like my custom QMyTreeItem(s) are replaced by QTreeWidgetItem(s).
Anybody who have a better understanding can help me please?

I am also wondering if solving the 1rst issue would solve the 2nd issue.

Best Regards
Lionel