仅在形状内部按下时才移动 QGraphicsItem。否则,拖动场景

Move QGraphicsItem only when pressing inside the shape. Otherwise, drag scene

我有一个 QGraphicsView 和一个更大的 QGraphicsScene 可以拖动。 在 QGraphicsScene 中,我有一个显示 QGraphicsPixmapItem 的子类 QGraphicsItem (TestItem),它可以具有随机形状。 (我没有直接使用QGraphicsPixmapItem,因为将来要实现额外的功能)

我希望这个项目是可移动的,但前提是用户在项目的形状内按下。如果在形状之外,但仍在 boundingRectangle 之内,我希望拖动它后面的场景。这是因为 boundingRectangle 可能比形状大得多并且用户看不到它,所以尝试将场景拖动到 Pixmap 附近并且它不起作用会很奇怪。

这是我的子分类项目:

TestItem::TestItem(QPointF position, QPixmap testImage, double width, 
                    double length, QGraphicsItem * parent):
    QGraphicsItem(parent),
    m_boundingRect(QRectF(0,0,5, 5)),
    m_dragValid(false),
    m_path(QPainterPath()),
    mp_image(new QGraphicsPixmapItem(this))
{
    setBoundingRect(QRectF(0,0,width,length));
    setPos(position - boundingRect().center());
    setFlag(QGraphicsItem::ItemIsMovable);
    mp_image->setPixmap(testImage.scaled(width, length));
    m_path = mp_image->shape();
}

QPainterPath TestItem::shape()
{
    return m_path;
} 

QRectF TestItem::boundingRect() const
{
    return m_boundingRect;
}

void TestItem::setBoundingRect(QRectF newRect)
{
    prepareGeometryChange();
    m_boundingRect = newRect;
}

我试过像这样覆盖鼠标事件,但它给我带来的只是在形状外但在边界矩形内时根本没有任何功能

void TestItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(shape().contains(event->pos()))
    { 
        QGraphicsItem::mousePressEvent(event);
        m_dragValid = true;
    }
}

void TestItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_dragValid)
        QGraphicsItem::mouseMoveEvent(event);
} 

void TestItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_dragValid)
        QGraphicsItem::mouseReleaseEvent(event);

    m_dragValid = false;
}

这当然有道理,但我不知道如何实现场景的拖动,因为是场景本身将鼠标事件发送到图形项。

(我的 QGraphicsView 设置为 DragMode QGraphicsView::ScrollHandDrag

有人有想法吗?

您只需要启用 QGraphicsItem::ItemClipsToShape 标志:

The item clips to its own shape. The item cannot draw or receive mouse, tablet, drag and drop or hover events outside its shape. It is disabled by default.

我明白了。我只需要在我的鼠标事件中添加一个 event->ignore();

void TestItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
   if(shape().contains(event->pos()))
    {  
        QGraphicsItem::mousePressEvent(event);
        m_dragValid = true;
    }
    else
        event->ignore();
}

void TestItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_dragValid)
         QGraphicsItem::mouseMoveEvent(event);
    else
        event->ignore();
} 

void TestItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_dragValid)
        QGraphicsItem::mouseReleaseEvent(event);
    else
        event->ignore();

    m_dragValid = false;
}