2

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

如果用户将 qgraphicsitem 拖到另一个区域而不是应该放置的 qgraphicsitem ,我还希望 qgraphicsitem 跳回其原始位置。

4

2 回答 2

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...()。

于 2013-07-30T09:26:21.087 回答
1

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

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

只需确保当您检查边界矩形的交集时,您是在场景空间坐标中对它们进行此操作。要么转换它们,要么使用 QGraphicsItem::sceneBoundingRect()。

于 2013-07-30T09:36:26.200 回答