QGraphicsView 中实现拖拽
来源:互联网 发布:国产js 12.7mm狙击步枪 编辑:程序博客网 时间:2024/06/10 05:38
开始想使用QGraphicsView结合QGraphicsScene和QGraphicsItem,做个绘制各种图形的编辑器,想使用拖拽实现快捷方式,没想到还有点波折。
已在QGraphicsVews中设置了setAcceptDrops(true);
在运行时发现:当把拖拽的图标放到QGraphicsVews上时,显示的还是不可拖拽的形状,但dragEnterEvent可以触发。但后面的dropEvent就不能触发了。
上网一查,视图接收到拖拽事件后会转交给关联的场景处理,但是在场景中重写dropevent还是没有扑捉到事件。
今天实际跟踪了一下:
1、拖拽首先进入QGraphicsView触发其dragEnterEvent事件:
- 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
- }
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}
上述函数主要是查看有没有场景,然后将事件转交给场景处理,当然是在条件允许的情况下转交给场景处理。
2、场景的dragEnterEvent
- void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
- {
- Q_D(QGraphicsScene);
- d->dragDropItem = 0;
- d->lastDropAction = Qt::IgnoreAction;
- event->accept();
- }
void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event){ Q_D(QGraphicsScene); d->dragDropItem = 0; d->lastDropAction = Qt::IgnoreAction; event->accept();}场景的dragenterEvent其实很简单就是接收拖拽事件
3、场景的dragMoveEvent事件,重点就在于此
- <SPAN style="COLOR: #333333">void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
- {
- Q_D(QGraphicsScene);
- </SPAN><SPAN style="COLOR: #ff0000">event->ignore();</SPAN><SPAN style="COLOR: #333333">
- 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);
- }
- }
- </SPAN>
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); }}
很显然,在拖拽移动过程中忽略了该事件,主要响应的是场景内可能存在的item拖拽事件
看到这,问题就有答案了,subclass场景类,重写dragMoveEvent
- void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
- {
- event->accept();
- }
void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){ event->accept();}
最后重写dropEvent,做最后拖拽处理就是了。
- <PRE class=cpp style="MARGIN: 4px 0px; BACKGROUND-COLOR: rgb(240,240,240)" name="code"></PRE>
- <PRE></PRE>
- QGraphicsView 中实现拖拽
- QGraphicsView 中实现拖拽
- QGraphicsView 实现动画实验
- QGraphicsView
- QGraphicsView
- QGraphicsView
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果
- Qt使用QGraphicsView实现滑动窗体效果 .
- Java UTF-8读写文本文件
- Hashtable 排序
- 设置IE兼容模式
- ECMall人工申诉找回密码
- 乔布斯的演讲——求知若饥,虚心若愚
- QGraphicsView 中实现拖拽
- Android 导入 Jar 包 出现: java.lang.NoclassDefFoundError 解决办法
- hdu 1576(数论之扩展欧几里得)
- Memory support in VxWorks
- 2013年面试总结,知道自己有哪些技术短板,好好补补吧。
- Graphics View框架
- vim
- MyBaits参数传递注意事项
- Qt使用QGraphicsView实现滑动窗体效果