I'm implementing a view and a model where I want to support both moving items internally (by dragging), and copying items (by pressing Ctrl while dragging). I've done everything I need to do according to the instructions. I've set up the mime functions, I've implemented removeRows(), and flags(). The problem is when I drag, it defaults to a copy operation (I get the arrow cursor with a plus sign, and it indeed copies the item by creating a new one in the model).
The only difference I can see is this: If I return only Qt::MoveAction in supportedDropActions(), it only moves. If I return (Qt::CopyAction | Qt::MoveAction), it only copies.
Any ideas? I want it to work like files in Nautilus (Gnome) or Windows file Explorer: drag moves icons around, ctrl+drag copies them.
I'm sorry I didn't follow up by answering this question when I found what I was doing wrong. The code that messed me up was in QAbstractItemView::startDrag()
:
if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
defaultDropAction = d->defaultDropAction;
else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
defaultDropAction = Qt::CopyAction;
The problem is I wasn't setting the defaultDropAction property on the widget as in setDefaultDropAction( Qt::MoveAction );
Therefore startDrag() was defaulting to CopyAction. If the defaultDropAction is Qt::MoveAction, then you can use the keyboard Ctrl to switch a drag in progress to a copy action, which is my desired behavior.
I love Qt, but there sure are a lot of confusing and somewhat intertwined properties related to drag/drop. It's easy to to not get the right combination of properties.
Bottom line: make sure to set the defaultDropAction to Qt::MoveAction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With