qt在qcraphicsScene中拖放

qt drag and drop in qgraphicsScene

本文关键字:拖放 qcraphicsScene qt      更新时间:2023-10-16

我在qgraphicsScene上有两个自定义的qgraphicItems,由qgraphicsview渲染。现在,我希望能够将两个项目中的一个拖放到另一个项目。但是,我应该重新考虑哪些事件呢?文档对此有点混淆。

此外,如果用户将qgraphicitem拖到应该放在上面的区域之外的另一个区域,我希望它能跳回原来的位置。

据我所知,这并没有在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);
}

这为一个QGraphicsScene完成了工作。如果您有其中两个,它们必须相互了解,并且必须将坐标从一个QGraphicsView转换到另一个QGraphicsView。正在使用mapTo。。。()。

关键是检查QGraphicsItems rect并查看它们是否相交。

因此,当鼠标按下项目时,存储其当前位置。您现在可以移动它并等待鼠标释放。释放鼠标按钮后,检查项目的边界矩形是否与QRect::contains(const QRectF)相交。如果他们这样做了,那么你就把一个扔到了另一个上面。如果没有,则将图形项设置回先前存储的位置的动画。

只要确保在检查边界矩形是否相交时,在场景空间坐标中使用这两个矩形即可。转换它们,或者使用QGraphicsItem::sceneBoundingRect()。