Implement drag and drop in qgraphicsview

Source: Internet
Author: User

At first, I wanted to use qgraphicsview in combination with qgraphicsscene and qgraphicsitem to create an editor for drawing various graphics. I did not expect any further twists and turns when I wanted to use drag and drop to implement shortcuts.

Setacceptdrops (true) has been set in qgraphicsvews );

During running, it is found that when the drag icon is placed on qgraphicsvews, the drag-and-drop shape is still displayed, but dragenterevent can be triggered. However, the dropevent cannot be triggered.

After a drag-and-drop event is received, the view forwards the event to the associated scenario for processing. However, the dropevent is not overwritten in the scenario.

Today, I actually tracked the following:

1. Drag it to qgraphicsview to trigger its dragenterevent event:

void QGraphicsView::dragEnterEvent(QDragEnterEvent *event){#ifndef QT_NO_DRAGANDDROP    Q_D(QGraphicsView);    if (!d->scene || !d->sceneInteractionAllowed)        return;    // Disable replaying of mouse move events.    d->useLastMouseEvent = false;    // Generate a scene event.    QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragEnter);    d->populateSceneDragDropEvent(&sceneEvent, event);    // Store it for later use.    d->storeDragDropEvent(&sceneEvent);    // Send it to the scene.    QApplication::sendEvent(d->scene, &sceneEvent);    // Accept the originating event if the scene accepted the scene event.    if (sceneEvent.isAccepted()) {        event->setAccepted(true);        event->setDropAction(sceneEvent.dropAction());    }#else    Q_UNUSED(event)#endif}

The above functions are mainly used to check whether there is a scenario, and then forward the event to the scenario for processing. Of course, they are transferred to the scenario for processing when conditions permit.

2. Scenario dragenterevent

void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event){    Q_D(QGraphicsScene);    d->dragDropItem = 0;    d->lastDropAction = Qt::IgnoreAction;    event->accept();}

The dragenterevent in the scenario is actually very easy to receive drag events.

3. This is the focus of the dragmoveevent event in the scenario.

void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){    Q_D(QGraphicsScene);    event->ignore();    if (!d->mouseGrabberItems.isEmpty()) {        // Mouse grabbers that start drag events lose the mouse grab.        d->clearMouseGrabber();        d->mouseGrabberButtonDownPos.clear();        d->mouseGrabberButtonDownScenePos.clear();        d->mouseGrabberButtonDownScreenPos.clear();    }    bool eventDelivered = false;    // Find the topmost enabled items under the cursor. They are all    // candidates for accepting drag & drop events.    foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),                                                     event->scenePos(),                                                     event->widget())) {        if (!item->isEnabled() || !item->acceptDrops())            continue;        if (item != d->dragDropItem) {            // Enter the new drag drop item. If it accepts the event, we send            // the leave to the parent item.            QGraphicsSceneDragDropEvent dragEnter(QEvent::GraphicsSceneDragEnter);            d->cloneDragDropEvent(&dragEnter, event);            dragEnter.setDropAction(event->proposedAction());            d->sendDragDropEvent(item, &dragEnter);            event->setAccepted(dragEnter.isAccepted());            event->setDropAction(dragEnter.dropAction());            if (!event->isAccepted()) {                // Propagate to the item under                continue;            }            d->lastDropAction = event->dropAction();            if (d->dragDropItem) {                // Leave the last drag drop item. A perfect implementation                // would set the position of this event to the point where                // this event and the last event intersect with the item's                // shape, but that's not easy to do.                  QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);                d->cloneDragDropEvent(&dragLeave, event);                d->sendDragDropEvent(d->dragDropItem, &dragLeave);            }            // We've got a new drag & drop item            d->dragDropItem = item;        }        // Send the move event.        event->setDropAction(d->lastDropAction);        event->accept();        d->sendDragDropEvent(item, event);        if (event->isAccepted())            d->lastDropAction = event->dropAction();        eventDelivered = true;        break;    }    if (!eventDelivered) {        if (d->dragDropItem) {            // Leave the last drag drop item            QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);            d->cloneDragDropEvent(&dragLeave, event);            d->sendDragDropEvent(d->dragDropItem, &dragLeave);            d->dragDropItem = 0;        }        // Propagate        event->setDropAction(Qt::IgnoreAction);    }}

Obviously, this event is ignored during the Drag and Drop Process, and the main response is the possible item drag events in the scenario.

If you see this, you will have an answer to the question. The subclass scenario class is rewritten to dragmoveevent.

void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){    event->accept();}

Rewrite the dropevent and perform the drag and drop operations.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.