1
votes

I'm trying to find a way, without re-implementing drag and drop, to have tree items expand when an item is dropped into them. I've looked into expand all on the top level addItem as well as over writing the dropEvent. The addItem approach doesn't work (assuming this is because addItem is not used by the native drag and drop implementation) and dropEvent presents a host of problems, specifically that mimeData is poorly suited and gives me a hook back into the tree. I'm new to Qt, so I may be missing something simple.

Any other approaches would be welcome.

Edit: working off of the information provided by @G.M. I've gone back to trying to overwrite dropEvent.

void ScenarioTreeWidget::MyTreeWidget::dropEvent(QDropEvent *event)
{
    QModelIndex modelIndex = this->indexAt(event->pos());
    QTreeWidgetItem* item = this->itemAt(modelIndex.row(), modelIndex.column());
    this->expandItem(item);
    QWidget::dropEvent(event);
}

Two issues, the item that is expanding is the one being dragged, not the item it is dropped onto (don't know if this is because the index is the index for the dragged item or if I have a bug in my code). Additionally I am still losing the default dropEvent behavior (when I drag on drop with this code all items stay where they were before the drag and drop).

1
Do you mean expand while you drag?peppe
No i mean, if i drag A into B, i want B to expand so that i can see A was placed inside it.James
I'm not sure I understand your comments about dropEvent. QDropEvent::pos gives you the position of the drop. That can be mapped and used as the argument to QTreeView::indexAt. Once you have that QModelIndex you can expand/collapse or do whatever you want with it.G.M.
Thanks for pointing me the right direction, I missed QDropEvent::pos though dropEvent still has some persistent problems. I've updated my questions to reflect the new information.James
You're using this->itemAt(modelIndex.row(), modelIndex.column()). I think what you actually want is this->itemFromIndex(modelIndex) or this->itemAt(event->pos()).G.M.

1 Answers

1
votes

You're passing the QModelIndex row and column to QTreeWidget::itemAt, but what it actually wants are the widget relative x and y coords.

Based on the info you've provided, I think what you need is something like...

void ScenarioTreeWidget::MyTreeWidget::dropEvent (QDropEvent *event)
{
  QModelIndex modelIndex = this->indexAt(event->pos());
  QTreeWidgetItem* item = this->itemAt(modelIndex);
  this->expandItem(item);
  QWidget::dropEvent(event);
}

or (a little bit more concisely)...

void ScenarioTreeWidget::MyTreeWidget::dropEvent (QDropEvent *event)
{
  QTreeWidgetItem* item = this->itemAt(event->pos());
  this->expandItem(item);
  QWidget::dropEvent(event);
}