How to draw a bounding rect around movable area of QGraphicsItem?

73 Views Asked by At

I made a custom QGraphicsItem and I am overriding the paint function to draw image which is ghost.png, a character that has a complex boundary, and can be moved by clicking on lower/upper/ left/right side of the image.

I understand this is happening because of the boundingRect, I am setting it larger because I need to draw something else, for example: text, health bar, etc...

How can I keep a larger boundingrect and also limit the image to move only if clicked on the image.

My class :

class DrawImage : public QGraphicsItem
{
public:
    DrawImage();

protected:
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};

My Definition :

DrawImage::DrawImage()
{
    setFlag(ItemIsMovable);
}

QRectF DrawImage::boundingRect() const
{
    return QRectF(0, 0, 100, 200);
}

void DrawImage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    auto ghost = QImage(":ghost.png");
    painter->drawImage(QRect(0, 0, 100, 100), ghost);
}
1

There are 1 best solutions below

0
A.R.M On

musicamante said:

Override [QGraphicsItem::]shape.

Here's how you can make your QGraphicsPixmapItem moveable only when clicked on its pixmap, and have a boundingRect around it:

class DrawImage : public QGraphicsItem
{
public:
    DrawImage()
    {
        setFlag(ItemIsMovable);
    }

protected:
    QRectF boundingRect() const override
    {
        return QRectF(0, 0, 100, 200);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        auto greenBall = QPixmap(":green.svg");
        QRect rect = boundingRect().toRect();

        //You can adjust where your pixmap is drawn
        //I chose the upper part of the bounding rect
        rect.adjust(0,0,0,-rect.height()/2);
        painter->drawPixmap(rect, greenBall);

        //I'm drawing the full bounding rect just to make it visible
        painter->setPen(Qt::green);
        painter->drawRect(boundingRect());
    }

    QPainterPath shape() const
    {
        //this is where you sepecify which area of your object allows the user to move it when clicked
        auto greenBall = QPixmap(":green.svg");
        QRect rect = boundingRect().toRect();
        
        //Make sure it is the same area where you're drawing your pixmap
        rect.adjust(0,0,0,-rect.height()/2);
        QPainterPath path;
        //add it as the shape you want, I chose an ellipse for the green circle
        path.addEllipse(rect);
        return path;
    }
};

Here's the result:

bounding rect around pixmap

See the source code for more details: