Starting Drag'n'Drop in QGraphicsScene::mouseMoveEvent()



  • Hello dear community!

    What I try to do
    I am trying to add Drag'n'Drop support to my QGraphicsScene to drag and drop items into other items. Also the normal move-functionality of the items should be retained (flag QGraphicsItem::ItemIsMovable).

    In the mouseMoveEvent() method I can tell if a new QDrag object should be created (by testing for a minimal drag distance etc.).

    Then I call QDrag::exec(), but when the drag operation is finished, items cannot be moved correctly anymore.

    My question:
    Is it okay to call QDrag::exec() from within mouseMoveEvent(), or more precisely between mouseEnterEvent() and mouseReleaseEvent()? Or is that unsupported?

    My guess why this fails
    I noticed that dragEnterEvent(), dragMoveEvent() and dropEvent() are called correctly, but no mouseReleaseEvent() after that anymore. I guess that QGraphicsScene needs for each mousePressEvent() a mouseReleaseEvent() to do some internal cleanup work.
    But after the drag operation started, the mouseReleaseEvent() is not called anymore, so I guess this leads to an invalid state within QGraphicsScene.

    I have prepared a minimal test application which shows the problem. I hope that this is the right place to ask the question? Or should I use the bug tracker instead?

    Thanks a lot for your help and time!
    Greetings Ingo


  • Moderators

    using mouseMoveEvent for starting the drag should be the correct way since QDrag::exec() calls processEvents internally. So all queued events will be send to their receivers.
    May it be that you dont call the base class implementations of the event handlers so the items stay in a wrong state?



  • Thanks for your answer!

    I think I am calling the base implementation (see my example below), in fact the problem also arises when I do not override mousePressEvent() or mouseReleaseEvent().

    In the example application you can move the rectangles, and while moving, press CTRL to start a drag. When you drop and move the same rectangle it jumps straight back to the position where it was, before the first move.

    What am I doing wrong?

    Example Application:
    @
    #include <QGraphicsRectItem>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    #include <QApplication>
    #include <QGraphicsSceneMouseEvent>
    #include <QMimeData>
    #include <QDrag>
    #include <iostream>

    class Scene : public QGraphicsScene {
    public:
    Scene() {
    QGraphicsRectItem* item;

    // add first item
    item = new QGraphicsRectItem();
    item->setRect(0, 0, 20, 20);
    item->setBrush(Qt::red);
    item->setFlag(QGraphicsItem::ItemIsSelectable);
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setPos(40, 40);
    addItem(item);

    // add second item
    item = new QGraphicsRectItem();
    item->setRect(0, 0, 20, 20);
    item->setBrush(Qt::blue);
    item->setFlag(QGraphicsItem::ItemIsSelectable);
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setPos(20, 60);
    addItem(item);
    }
    virtual ~Scene() {
    }
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
    QGraphicsScene::mouseMoveEvent(event);

     if (event->buttons() != 0 && event->modifiers() != 0) {
      // perform drag
      QMimeData* mimeData = new QMimeData();
      QDrag* drag = new QDrag(event->widget());
      drag->setMimeData(mimeData);
      drag->exec&#40;&#41;;
     }
    }
    
    
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event&#41; {
     QGraphicsScene::mousePressEvent(event&#41;;
     std::cout << "mousePressed" << std::endl;
    }
    
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event&#41; {
     QGraphicsScene::mouseReleaseEvent(event);
     std::cout << "mouseRelease" << std::endl;
    }
    

    };

    int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    Scene* scene = new Scene();

    QGraphicsView* view = new QGraphicsView(scene);
    view->setAcceptDrops(true);
    view->setDragMode(QGraphicsView::RubberBandDrag);
    view->setAlignment(Qt::AlignCenter);
    view->setMouseTracking(true);
    view->show();

    return app.exec();
    }
    @




Log in to reply
 

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