[Qt-interest] I still need help moving items in a QTreeWidget

Bob Hood bhood2 at comcast.net
Tue Feb 8 19:26:33 CET 2011


I have drag-and-drop in my QTreeWidget working now.  However, I still need
some insight from somebody.  When the dropEvent() finally occurs, I cannot
seem to find a way to determine where the drop will actually end up.  In other
words, the visual cues that are provided during the drag operation indicate
either an insertion (dropping between two other children), or a re-parenting
(dropping the dragged child onto another child causes re-parenting).  I want
to disallow this re-parenting, but I cannot find a way to determine if the
drop point will be an insert or if it will be a re-parent.  In effect, I want
the children under a top-level parent to be moved around like a QListWidget --
no parenting allowed.

Here's my dropEvent() logic:

    void MyTreeWidget::dropEvent(QDropEvent *e)
    {
        const QMimeData* mime_data = e->mimeData();
        if(!mime_data->hasFormat("application/mytype"))
        {
            e->ignore();
            return;
        }

        if(e->keyboardModifiers() == Qt::NoModifier)
        {
            const QPoint pos = e->pos();
            QTreeWidgetItem* target = itemAt(e->pos());

            bool do_move = true;

            // this is used to determine if the target is itself a child
            if(target->parent() != (QTreeWidgetItem*)0)
                do_move = false;
            else
            {
                foreach(QTreeWidgetItem* item, selected_items)
                {
                    // if target and item don't share the same parent...
                    if(target->parent() != item->parent())
                    {
                        // ...then don't allow the move
                        do_move = false;
                        break;
                    }
                }
            }

            if(!do_move)
                e->setDropAction(Qt::IgnoreAction);
            else
            {
                QTreeWidget::dropEvent(e);
                e->setDropAction(Qt::TargetMoveAction);
            }

            e->accept();
        }
        else if(e->proposedAction() == Qt::TargetMoveAction)
        {
            QTreeWidget::dropEvent(e);
            e->acceptProposedAction();
        }
        else
            QTreeWidget::dropEvent(e);
    }

The problem is, with an insertion, the line:

    QTreeWidgetItem* target = itemAt(e->pos());

still returns a child item, even though the visual feedback says that the drop
will be inserted above (or below) it.  Without knowing this difference, how
can I disallow re-parenting?



More information about the Qt-interest-old mailing list