QGraphicsScene drag and drop
-
wrote on 12 Jan 2011, 21:24 last edited by
I have a QGraphicsScene based class that accepts drops and everything works ok.
But QGraphicsWidget derived classes i have do not accept drops.@void Scene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
//here
SourceWidget *source = qobject_cast<SourceWidget *>(event->source());
if(source) {
event->setDropAction(Qt::CopyAction);
event->accept();
}
}void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
SourceWidget *source = qobject_cast<SourceWidget *>(event->source());
if(source) {
event->setDropAction(Qt::CopyAction);
event->accept();
}}
void Scene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
SourceWidget *source = qobject_cast<SourceWidget *>(event->source());
if(source) {
createWidget(static_castWidget::WidgetType(event->mimeData()->text().toInt()), event->scenePos());
event->setDropAction(Qt::CopyAction);
event->accept();
}
}@this works super but when using the same code in a qgraphicswidget based class ( with accept drops set to true)
the code dose not even reach to the point of the //here comment when removing the 3 handlers from the scene class the items accept drops OK.
I'm just curios if the scene accepts drops items can't? -
wrote on 13 Jan 2011, 07:47 last edited by
Reimplementing virtual methods is always tricky. I think your problem is, is that your Scene implementation doesn't call the base class implementation of the virtual methods you reimplemented. This way, you disabled Qt's own event propagation mechanisms that are implemented in the base classes.
Unless you're sure you should not, always call the base class implementation in your reimplementation of a virtual class. It may do actual work you were not aware of.
-
wrote on 13 Jan 2011, 11:52 last edited by
Thanks for the answer I thought that to.
-
wrote on 13 Jan 2011, 12:10 last edited by
What is the error on //here?
Is the method called at all?
Is it called but you do not get into accepting the event? -
wrote on 13 Jan 2011, 12:21 last edited by
[quote author="Olorin5800" date="1294919561"]Thanks for the answer I thought that to.[/quote]
But...? That doesn't solve your issue? -
wrote on 13 Jan 2011, 12:48 last edited by
[quote author="Andre" date="1294921290"]
[quote author="Olorin5800" date="1294919561"]Thanks for the answer I thought that to.[/quote]
But...? That doesn't solve your issue?[/quote]
Can't test right now but looking through the qt source code not calling the base implementation seems to be the problem in the qgraphicsscene implementation of the drag move event is where the forwarding is taking place my code overrides the event and never calls the parent.
[quote author="Volker" date="1294920632"]What is the error on //here?
Is the method called at all?
Is it called but you do not get into accepting the event?[/quote]No error the method where t i put the comment is not called in the item class if overriding the scene implementation of drag enter, drag move and drop events.
-
wrote on 13 Jan 2011, 12:56 last edited by
gnarf ... of course it does not call the dragEnterEvent method of your item if the scene already accepts the drag!
If you eventually drop your drag - there is only one object to receive it - it's that one, that accepted the dragEnter/dragMove events.
Hypothetically, if you allowed both to dragEnter, which one should get the drop at the end? Both? The top one (on z-order)? The bottom one? Rolling dices?
-
wrote on 13 Jan 2011, 13:11 last edited by
[quote author="Volker" date="1294923392"]gnarf ... of course it does not call the dragEnterEvent method of your item if the scene already accepts the drag!
If you eventually drop your drag - there is only one object to receive it - it's that one, that accepted the dragEnter/dragMove events.
Hypothetically, if you allowed both to dragEnter, which one should get the drop at the end? Both? The top one (on z-order)? The bottom one? Rolling dices?[/quote]
Yes I realized that ( after posting :D ) anyway modifing the above code like so to allow graphics scene to forward the event
@void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
QGraphicsScene::dragMoveEvent(event);
SourceWidget *source = qobject_cast<SourceWidget *>(event->source());
if(source) {
event->setDropAction(Qt::CopyAction);
event->accept();
}}
void Scene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
QGraphicsScene::dropEvent(event);
SourceWidget *source = qobject_cast<SourceWidget *>(event->source());
if(source) {
createWidget(static_castWidget::WidgetType(event->mimeData()->text().toInt()), event->scenePos());
event->setDropAction(Qt::CopyAction);
event->accept();
}
}@the drag enter and drop events are called for the items correctly.
as for who accepts the drop in my application that depend on the contents of mime type (scene accepts images for example and item accept text drops).Thanks everyone for your help.
-
wrote on 13 Jan 2011, 13:35 last edited by
So it does work now?
-
wrote on 13 Jan 2011, 13:43 last edited by
Yes it works now.
-
wrote on 20 Dec 2011, 15:01 last edited by
I had the same problem. Olorin's code worked for me. Thanks for the follow up.