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.
removeRows()
called after dropMimeData()
? removeRows()
manually in dropMimeData()
? 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.
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.
setDragEnabled
: enables the builtin drag mechanism setAcceptDrops
: enables the builtin drop mechanism 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, ie 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.
I think yes, you have to call removeRows()
from the dropMimeData()
if the Qt::DropAction
is Qt::MoveAction
, ie 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.