2
votes

I have a QTreeWidget which I have setup like so...

ModelTreeWidget::ModelTreeWidget(QWidget *parent):QTreeWidget(parent), mpModelStruct(nullptr), mpModeldragging(nullptr), mpBufferModel(nullptr), mpModelCurrent(nullptr)
{

    setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed);
    setColumnCount(1);
    setSelectionMode(QAbstractItemView::SingleSelection);

    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDragDropMode(QAbstractItemView::DragDrop);
    setDefaultDropAction(Qt::MoveAction);

}

I've also overwritten my drop event, but it's fairly innocuous:

void ModelTreeWidget::dropEvent(QDropEvent* event)
{
    QTreeWidget::dropEvent(event);
}

Supported action is MoveAction:

Qt::DropActions ModelTreeWidget::supportedDropActions() const
{
    return Qt::MoveAction;
}

Each item has the flags:

Qt::ItemFlags ModelTreeWidget::getTreeItemFlags() const
{
    return (Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}

Now when I populate my tree widget with items, I can drag one item over another, and it becomes added as a child to the item I dragged onto. However when I try to drag an item between two other items, I don't get an indicator (which I think should be a line) between the two rows. I just get the not allowed indicator.

My question is, how do I enable insertion of an item between two other items using drag and drop for QTreeWidget?

Edit: I setup my tree root using the following code:

        QTreeWidgetItem* rootId = new QTreeWidgetItem((QTreeWidget*)0, QStringList(currentModel->name));
        QVariant v = qVariantFromValue((void *) currentModel);
        rootId->setData(0, Qt::UserRole, v);
        rootId->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
        insertTopLevelItem(0, rootId);

While each child of my root is setup as the following:

            QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList(tempModel->name));
            QVariant v = qVariantFromValue((void *) tempModel);
            item->setData(0, Qt::UserRole, v);
            item->setFlags(getTreeItemFlags());
            parent->addChild(item);
1

1 Answers

2
votes

It seems that there are two problems here. One is that my supportedDropActions() only supported MoveAction, which seems to interfere with the drag n drop insert function, which add and delete data around. The symptoms of this were that each time I inserted data between two entries in a basic test QTreeWidget class, it would also erase the element before the object I was dragging. By adding Qt::CopyAction so that my supportedDropActions() looks like

Qt::DropActions ModelTreeWidget::supportedDropActions() const
{
    return (Qt::MoveAction | Qt::CopyAction);
}

Fixed the prob of drag and drop insertions between entries deleting an entry each time it moved. However, this didn't fix my actual problem asked in this post.

What fixed my actual problem was not manually setting my tree root's flags.

        QTreeWidgetItem* rootId = new QTreeWidgetItem((QTreeWidget*)0, QStringList(currentModel->name));
        QVariant v = qVariantFromValue((void *) currentModel);
        rootId->setData(0, Qt::UserRole, v);
//Commented this out        rootId->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
        insertTopLevelItem(0, rootId);

Doing so solved my problem. I'm still not completely sure why that would interfere with the insertion operation but it did.