【问题标题】:Qt: Resizing a png image on Mouse Move Event does not work when resized from left or top side of the rectQt:从矩形的左侧或顶部调整大小时,在鼠标移动事件上调整 png 图像的大小不起作用
【发布时间】:2014-05-02 20:41:38
【问题描述】:

我有一个在图形场景中显示为 QGraphicsPixmapItem 的 png 图像。 图像是矩形的。每次在矩形的任何一侧(即从左、右、上或下)被鼠标移动事件拖动时,我都需要调整 png 图像的大小。

目前我只能在从右侧和底部拖动时调整图像大小。从左侧和顶部拖动时,图像大小调整失败。请让我知道下面代码中的错误。这里调整大小是基于最大尺寸的原始图像文件,但场景本身显示的初始图像是源图像的缩小版本。

部分代码贴在下面,我没有展示 hoverEnterEvent() 实现:

  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);
     }

【问题讨论】:

  • 现在直接在类中存储图片,只需要继承QGraphicsItem,不需要QGraphicsPixmapItem。当您尝试从左上角调整大小时会看到什么?
  • 我使用 QGraphicsPixmapItem 因为最初的图像本身是源图像的缩小版本。 image_rect 初始值取自第一次显示的初始缩放图像。当我从矩形的顶部或左侧调整大小时,图像会移动并且不会调整大小。我的逻辑基于使用锚点调整大小。锚点是 top_left 和 bottom_right 点。目前,我的图片无法锚定在右下角。
  • Merlin069- Merlin,您能否尝试回答我关于如何绘制垂直于 QGraphicsLineItem 的矩形的问题之一。我真的非常需要你的帮助。

标签: qt qgraphicsitem qgraphicsscene


【解决方案1】:

我尝试了以下代码来调整矩形的大小,它可以工作。在 mouseMoveEvent() 的早期版本中,我总是尝试在每次调整大小后将 topLeft 坐标设置为 (0,0)。 在新版本中,我让 topLeft 坐标保持在它们所在的位置,并且在每次调整大小后都不会费心将 topLeft 设置为 (0,0)。调整大小后,topLeft 永远不会在本地坐标中设置为原点。

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();

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多