سؤال

I have some problem with drag and drop in QTreeView:

I set flag to Qt::MoveAction and reimplemented removeRows(), dropMimeData() and etc in my model. The Model inherits QAbstractItemModel.

When I drag and drop, mimeData(), dropMimeData() are called automatically, and also dropMimeData() calls insertRows() automatcally. But removeRows() is not called, so the dragged item is still alive. I googled, but they said their removeRows() was called automatically.

  • Why isn't my removeRows() called after dropMimeData()?
  • Shoud I call removeRows() manually in dropMimeData()?
  • If so, how can I know the previous QModelIndex of start of drag?

When starting drag, in mimeData(), I can save index in private member, but it looks like not good.

Any advice would be appreciated.

هل كانت مفيدة؟

المحلول 3

I think yes, you have to call removeRows() from the dropMimeData() if the Qt::DropAction is Qt::MoveAction, i.e. you completely move your tree node from one place to another.

WRT your second question, you can create your custom mime data in QAbstractItemModel::mimeData() and encode your dragged nodes initial information there. So, in dropMimeData() function you can decode and use it.

نصائح أخرى

Short answer

If everything is correctly configured, the target should not remove the source item, the initiator of the drag should remove the source item if a Qt::MoveAction is performed.

Configuration of the view

QAbstractItemView (which is the base class of QTreeView, QListView, QTableView, ...) implements the initiation and finishing of the QDrag operation in startDrag:

if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
    d->clearOrRemove();

So, when the requested drop action (returned by QDrag::exec) is a Qt::MoveAction, the item is automatically removed (or cleared as specified by setDragDropOverwriteMode).

Important configuration options of the view are:

  • setDragDropMode: specifies if the view should accept drag and/or drop items from external or only internal items. This function calls setDragEnabled and setAcceptDrops accordingly.

  • setDragDropOverwriteMode: specifies if the source item should be removed (typical in a tree view) or cleared (typical in a table view)

  • setDefaultDropAction: the default drop action specified when initiating the QDrag operation.

Configuration of the model

Besides the configuration of the view, you should configure your model correctly.

  • You should implement the editing interface of your model, i.e. removeRows, insertRows, moveRows and setData. Although it may not be necessary to implement all of them depending on your specific situation, it is a good approach to implement them anyway for an editable model.

  • supportedDropActions: Reimplement this function to return the support drop actions (Qt::CopyAction by default). Note that the user may switch between the different supported actions by pressing some keys. (shift for Qt::MoveAction and control for Qt::CopyAction)

    • supportedDragActions: Reimplement this function if the supported drag actions are different from the supported drop actions.

Examples

Good examples are the source code of Qt itself. The corresponding Q*Widget classes (ex. QTreeWidget for QTreeView) are provides concrete implementations of the view and a corresponding model.

I had the same issue with my custom model. Setting dragDropOverwriteMode=false for view resolved my problem.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top