我在qgraphicsScene上有2个自定义qgraphicsitems,由qgraphicsview呈现。现在我希望能够将2个项目中的一个拖放到另一个项目中。但是我应该为此重新实现哪些事件?文档在这方面有点令人困惑。
我还想让qgraphicsitem跳回原来的位置,如果用户将它拖到另一个区域,而不是应该放在它上面的qgraphicsitem。
答案 0 :(得分:5)
据我所知,QGraphicsScene本身没有实现。 您必须从QGraphicsView或QGraphicsScene派生自己的类,然后重载:
class MyGraphicsView : public QGraphicsView
{
Q_OBJECT;
protected:
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);
...
private:
QGraphicsItem *currentDraggedItem;
};
QGraphicsView提供视图/窗口坐标的工作,而QGraphicsScene使用场景坐标。
添加如下代码:
void MyGraphicsView::mousePressEvent(QMouseEvent* event)
{
currentDraggedItem = itemAt(event->pos());
QGraphicsView::mousePressEvent(event);
}
void MyGraphicsView::mouseReleaseEvent(QMouseEvent* event)
{
QGraphicsItem *foundItem = itemAt(event->pos());
if(foundItem && currentDraggedItem &&
foundItem != currentDraggedItem)
{
// Handle DragDrop Here
}
QGraphicsView::mouseReleaseEvent(event);
}
这是一个 QGaphicsScene的工作。如果你有两个 - 两者必须相互了解,你必须将坐标从一个QGraphicsView转换到另一个QGraphicsView。使用mapTo ...()。
答案 1 :(得分:1)
关键是检查QGraphicsItems rect并查看它们是否相交。
因此,当在项目上按下鼠标时,存储其当前位置。您现在可以移动它并等待鼠标释放。在释放鼠标按钮时,检查项目的边界是否与QRect :: contains(const QRectF)相交。如果他们这样做,那么你就把一个放到另一个上。如果没有,则将图形项动画回原先存储的位置。
当你在场景空间坐标中检查你正在对它们两者进行交叉的边界时,确保当你正在检查它们。要么转换它们,要么使用QGraphicsItem :: sceneBoundingRect()。