PDA

View Full Version : Drag from tree widget



EricF
14th December 2007, 19:41
I have subclassed QTreeWidget and want to enable drag and drop for it.

Every thing works except one thing. When I drag elements from the tree widget, it copies the element. I would like to copy element when dragging from outside the tree widget and move element when dragging from the tree widget. I know there is a setSupportedDragActions in QAbstractItemModel but I can't use it since model() function returns a const.

There must be a way to do this and not subclass a model right ?

One more question, when starting a drag with Qt::CopyAction and Qt::MoveAction and dropping on a widget that accept only Qt::MoveAction, will dropMimeData be called for each drop actions specified in the startDrag ? If so, how could I know where the drag comes from ?

aamer4yu
15th December 2007, 10:43
If so, how could I know where the drag comes from ?
i guess u have a look at QWidget * QDrag::source (); and also target.

wysota
15th December 2007, 12:22
I know there is a setSupportedDragActions in QAbstractItemModel but I can't use it since model() function returns a const.

You can use const_cast to get rid of the const modifier.

QAbstractItemModel *mdl = const_cast<QAbstractItemModel*>(model());

EricF
15th December 2007, 18:28
Yeah I know that but I just thought Trolltech made it const for a reason. And in the dropMimeData, I don't have access to QDrag object.

wysota
15th December 2007, 18:32
Sure. You shouldn't access the model using the non-model approach, but if you need to alter the drag actions, then you have no other choice. The tree class obviously misses the setSupportedDragActions method. it should be safe to use the one from the model though. I suggest you try it.

In dropMimeData() I think you can alter the drop action if you are able to determine the source of the drag just by the contents. If not, you can reimplement dragEnterEvent in the view and do the check (and change the drag action) there although it breaks the model-view separation a bit. Unfortunately currently there is no better choice.

EricF
15th December 2007, 22:02
Thanks that's a great point of view, I'll try that.

EricF
17th December 2007, 16:02
Ok to get the fact straight, the model() function is not const, I must have been tired when I first look at the documentation. So I tried setting the supportedDracAction on it and it worked when startDrag was called but for some reason, when dragEnter, dragMove and dropEvent were called, I always got the proposed action to be Qt::CopyAction which seemed weird when I set Qt::MoveAction.

QDrag::start functions add Qt::CopyAction no matter what suggested drop actions were. I then continued to trace and got to the platform specific implementation which I didn't want to understand. I chose Qt for a reason afterall :rolleyes:

So after trying some stuff, I needed to reimplement dropEvent only to set the right dropAction based on drag source because in dropMimeData, there is no way that I know of to know what is the drag source.

So that was my solution.

wysota
17th December 2007, 16:28
QDrag::start functions add Qt::CopyAction no matter what suggested drop actions were.
I seem to remember this is a necessity on Windows.


... because in dropMimeData, there is no way that I know of to know what is the drag source.

If you are the one creating the mime data, you can subclass it or provide the data you need in some other way to carry it with the object to the drop site.

EricF
17th December 2007, 18:59
I seem to remember this is a necessity on Windows.This was part of QDrag implementation, QDrag::start adds Qt::CopyAction not the windows specific implementation. It's kind of funny though as this function is declared obsolete and they still use it. QDrag::exec() accepts a defaultDrop which would to the trick I think.




If you are the one creating the mime data, you can subclass it or provide the data you need in some other way to carry it with the object to the drop site. Yeah I know because I'm already subclassing the mime data, it's just that I didn't want to add data for this specific drop target. Anyway, it works now. Thanks, again.

wysota
17th December 2007, 23:09
This was part of QDrag implementation, QDrag::start adds Qt::CopyAction not the windows specific implementation.
I meant that Windows requires it (don't ask me why) and so it's implemented on all platforms to keep compatibility.