qt拖放qgraphicsScene

时间:2013-07-30 09:18:57

标签: c++ qt drag-and-drop qgraphicsitem

我在qgraphicsScene上有2个自定义qgraphicsitems,由qgraphicsview呈现。现在我希望能够将2个项目中的一个拖放到另一个项目中。但是我应该为此重新实现哪些事件?文档在这方面有点令人困惑。

我还想让qgraphicsitem跳回原来的位置,如果用户将它拖到另一个区域,而不是应该放在它上面的qgraphicsitem。

2 个答案:

答案 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()。