QGraphicsScene drag and drop



  • 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?



  • 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.



  • Thanks for the answer I thought that to.



  • 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 author="Olorin5800" date="1294919561"]Thanks for the answer I thought that to.[/quote]
    But...? That doesn't solve your issue?



  • [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.



  • 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 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.



  • So it does work now?



  • Yes it works now.



  • I had the same problem. Olorin's code worked for me. Thanks for the follow up.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.