0

I have a png image which is displayed on the graphics scene as a QGraphicsPixmapItem. The image is rectangular in shape. I need to resize the png image every time it is dragged by a mouse move event on any side of the rectangle ie, from left,right,top or bottom.

Currently I am able to resize the image only when dragged from right and bottom sides only. Image resizing fails when dragged from left and top side. Please let me know the mistakes in my code below. Here Resizing is based on original image file which is of maximum size, but the initial image displayed on the scene itself is a scaled down version of source image.

The partial code is posted below, I have not shown hoverEnterEvent() implementation:

  PersonSizeGraphicsItem::PersonSizeGraphicsItem(const QPixmap &pixmap, QGraphicsScene *scene)
        :QGraphicsPixmapItem(pixmap, 0, scene)
    {
        this->setFlag(QGraphicsItem::ItemIsMovable, true);
        this->setFlag(QGraphicsItem::ItemIsSelectable, true);
        this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
        this->setFlag(QGraphicsItem::ItemIsFocusable, true);
        this->setFocus(Qt::MouseFocusReason);
        this->setAcceptHoverEvents(true);
        //this->setScale(0.5);

        rect_left_condition = false;
        rect_right_condition = false;
        rect_top_condition = false;
        rect_bottom_condition = false;
        rect_resize_occurred = false;
        image_rect = QRect();
        image_rect =  this->pixmap().toImage().rect();
    }

    PersonSizeGraphicsItem::~PersonSizeGraphicsItem()
    {

    }

    int PersonSizeGraphicsItem::type() const
    {
        return item_type;
    }

    void PersonSizeGraphicsItem::setSourceImage(const QImage& source_image)
    {
        this->source_image =  source_image;
    } 

    void PersonSizeGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        const QPointF event_pos = event->pos();
        const QPointF event_scene_pos = event->scenePos();

            QPoint current_top_left = image_rect.topLeft();
        QPoint current_bottom_right = image_rect.bottomRight();

        if((event->scenePos().x() > this->scene()->width()) || (event->scenePos().y() > this->scene()->height())
            || (event->scenePos().x() < 0) || (event->scenePos().y() < 0) )
        {
            return;
        }

        if( this->cursor().shape() == Qt::SizeHorCursor )
        {
            if(rect_right_condition)
            {

                image_rect = QRect( current_top_left, QPoint( event->pos().x(), current_bottom_right.y()) );


                rect_resize_occurred = true;
            }

            if(rect_left_condition)
            {
                image_rect = QRect( QPoint(event_pos.x(), 0), current_bottom_right );

                QPoint new_top_left = image_rect.topLeft();
                QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
                this->setPos(mapped_topLeft);
                rect_resize_occurred = true;

                //qDebug() << "new rectangle top left:" << this->pixmap().rect().topLeft();
            }

        }

        if( this->cursor().shape() == Qt::SizeVerCursor )
        {
            if(rect_bottom_condition)
            {
                image_rect = QRect(current_top_left, QPoint(current_bottom_right.x(), event->pos().y()));


                rect_resize_occurred = true;
            }

            if(rect_top_condition)
            {
                image_rect = QRect(QPoint(0, event_pos.y()), current_bottom_right);

                QPoint new_top_left = image_rect.topLeft();
                QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
                this->setPos(mapped_topLeft);

                qDebug() << "new rectangle top left###:" << this->pixmap().rect().topLeft();
                rect_resize_occurred = true;

            }
        }

        this->update();

    }


    void PersonSizeGraphicsItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        painter->drawImage(image_rect, source_image);
    }



     QRectF PersonSizeGraphicsItem:: boundingRect() const
     {
        qreal extra = 0.0;

          QRect rect = image_rect;
          return QRectF(rect.topLeft(), QSizeF(rect.width(), rect.height()))
            .normalized()
            .adjusted(-extra, -extra, extra, extra);
     }
jeevan_reddy
  • 43
  • 1
  • 10
  • Now that you're directly storing the image in the class, you only need inherit from QGraphicsItem, not QGraphicsPixmapItem. What do you see when you try to resize from the top left? – TheDarkKnight May 01 '14 at 14:08
  • I used QGraphicsPixmapItem because the initially image itself is a scaled down version of the source image. The image_rect intial values are taken from the initial scaled image which is displayed first time.When I resize from either the top or the left side of rectangle, the image moves and does not resize. My logic is based on resizing using anchor points. The anchor points are top_left and bottom_right points. Currently, I image is unable to anchor on bottom right. – jeevan_reddy May 01 '14 at 14:25
  • Merlin069- Merlin, Could you please try and answer one of my questions on how to draw a rectangle perpendicular to the QGraphicsLineItem. I really need your help on that badly. – jeevan_reddy May 05 '14 at 05:19

1 Answers1

0

I tried the following code to resize the rectangle and it works. In the earlier version of mouseMoveEvent(), I always tried to smehow set the topLeft coordinates to (0,0) each time after resize is done. In the new version, I let the topLeft coordinates remain where they are and not bother to set the topLeft to (0,0) after each resize. Once the resize is done, the topLeft is never set to origin here in local coordinates.

void PersonSizeGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF event_pos = event->pos();
    const QPointF event_scene_pos = event->scenePos();

    QPoint current_top_left = image_rect.topLeft();
    QPoint current_bottom_right = image_rect.bottomRight();

    if((event->scenePos().x() > this->scene()->width()) || (event->scenePos().y() > this->scene()->height())
        || (event->scenePos().x() < 0) || (event->scenePos().y() < 0) )
    {
        return;
    }

    if( this->cursor().shape() == Qt::SizeHorCursor )
    {
        if(rect_right_condition)
        {

            image_rect = QRect( current_top_left, QPoint( event->pos().x(), current_bottom_right.y()) );

            if( image_rect.width() <=8 || image_rect.height() <=24 )
            {
                return;
            }

            rect_resize_occurred = true;
        }

        if(rect_left_condition)
        {
            //image_rect = QRect( QPoint(event_pos.x(), 0), current_bottom_right );

            image_rect = QRect( QPoint(event_pos.x(), current_top_left.y()), current_bottom_right );

            if( image_rect.width() <=8 || image_rect.height() <=24 )
            {
                return;
            }
            rect_resize_occurred = true;

        /*  QPoint new_top_left = image_rect.topLeft();
            QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
            this->setPos(mapped_topLeft); */

            //qDebug() << "new rectangle top left:" << this->pixmap().rect().topLeft();
        }

    }

    if( this->cursor().shape() == Qt::SizeVerCursor )
    {
        if(rect_bottom_condition)
        {
            image_rect = QRect(current_top_left, QPoint(current_bottom_right.x(), event->pos().y()));

            if( image_rect.width() <=8 || image_rect.height() <=24 )
            {
                return;
            }

            rect_resize_occurred = true;
        }

        if(rect_top_condition)
        {
            //image_rect = QRect(QPoint(0, event_pos.y()), current_bottom_right);

            image_rect = QRect(QPoint(current_top_left.x(), event_pos.y()), current_bottom_right);

            if( image_rect.width() <=8 || image_rect.height() <=24 )
            {
                return;
            }

        /*  QPoint new_top_left = image_rect.topLeft();
            QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
            this->setPos(mapped_topLeft); */

            rect_resize_occurred = true;

        }
    }

    this->update();

}
jeevan_reddy
  • 43
  • 1
  • 10