QGraphicsItem鼠标拖动图元进行缩放拉伸(四)

这篇具有很好参考价值的文章主要介绍了QGraphicsItem鼠标拖动图元进行缩放拉伸(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

QGraphicsItem图元的简单使用(一)
QGraphicsItem图元拖动绘制(二)
QGraphicsItem图元旋转缩放和自定义图元(三)



前言

接上一篇,本章将讲解如何通过鼠标拖动图元进行缩放拉伸


一、演示效果

QGraphicsItem鼠标拖动图元进行缩放拉伸(四)

二、相关代码

需要先在打开图元接受鼠标悬浮事件的开关,构造函数中添加如下代码:

    // 接收鼠标悬浮事件
    this->setAcceptHoverEvents(true);

计算鼠标各个悬浮区域,鼠标悬浮时,显示不同的鼠标样式

void RectItem::UpdateHandlesArea()
{
    QRectF rect = this->boundingRect();

    m_handlesArea[Mouse_LeftTop] = QRectF(rect.left(), rect.top(), m_dHandleSize, m_dHandleSize);                           // 左上
    m_handlesArea[Mouse_RightTop] = QRectF(rect.right() - m_dHandleSize, rect.top(), m_dHandleSize, m_dHandleSize);         // 右上
    m_handlesArea[Mouse_LeftBottom] = QRectF(rect.left(), rect.bottom() - m_dHandleSize, m_dHandleSize, m_dHandleSize);     // 左下
    m_handlesArea[Mouse_RightBottom] = QRectF(rect.right() - m_dHandleSize, rect.bottom() - m_dHandleSize, m_dHandleSize, m_dHandleSize);   // 右下
    m_handlesArea[Mouse_MiddleTop] = QRectF(rect.center().x() - m_dHandleSize / 2, rect.top(), m_dHandleSize, m_dHandleSize);     // 中上
    m_handlesArea[Mouse_MiddleBottom] = QRectF(rect.center().x() - m_dHandleSize / 2, rect.bottom() - m_dHandleSize, m_dHandleSize, m_dHandleSize);
    m_handlesArea[Mouse_MiddleLeft] = QRectF(rect.left(), rect.center().y() - m_dHandleSize / 2, m_dHandleSize, m_dHandleSize);    // 中左
    m_handlesArea[Mouse_MiddleRight] = QRectF(rect.right() - m_dHandleSize, rect.center().y() + m_dHandleSize / 2, m_dHandleSize, m_dHandleSize);
}

鼠标相关事件重写

void RectItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    if(this->isSelected())
    {
        m_eMouseHandle = GetMouseHandle(event->pos());
        switch (m_eMouseHandle) {
        case Mouse_LeftTop:         // 左上
        case Mouse_RightBottom:     // 右下
            this->setCursor(Qt::SizeFDiagCursor);
            break;
        case Mouse_LeftBottom:      // 左下
        case Mouse_RightTop:        // 右上
            this->setCursor(Qt::SizeBDiagCursor);
            break;
        case Mouse_MiddleTop:       // 上
        case Mouse_MiddleBottom:    // 下
            this->setCursor(Qt::SizeVerCursor);
            break;
        case Mouse_MiddleLeft:      // 左
        case Mouse_MiddleRight:     // 右
            this->setCursor(Qt::SizeHorCursor);
            break;
        default:
            this->setCursor(Qt::SizeAllCursor);
            break;
        }
    }

    return QGraphicsItem::hoverEnterEvent(event);
}

void RectItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    m_eMouseHandle = Mouse_None;       // 无
    this->setCursor(Qt::ArrowCursor);

    return QGraphicsItem::hoverLeaveEvent(event);
}

void RectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)  // 左键按下
    {
        // 当前选中图形边缘,进行图元尺寸改变处理
        if(m_eMouseHandle != Mouse_None)
        {
            m_pressRect = boundingRect();
            return;
        }
    }

    return QGraphicsItem::mousePressEvent(event);
}

void RectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->buttons() == Qt::LeftButton)  // 左键按下
    {
        // 处理鼠标第一次绘制时的拖动
        if(m_bDrawFlag)
        {
            return;
        }

        // 处理鼠标拖动缩放图元时绘制
        if(m_eMouseHandle != Mouse_None)
        {
            ResizeRect(event->pos());
            return;
        }
    }
    return QGraphicsItem::mouseMoveEvent(event);
}

void RectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    // 防止鼠标右键弹出菜单后,左击移动
    if (event->button() == Qt::LeftButton)  // 左键按下
    {
        // 只处理上下拖动
        if(m_eMouseHandle != Mouse_None)
        {
            // 拖动结束后恢复选中
            this->setSelected(true);
        }
    }

    return QGraphicsItem::mouseReleaseEvent(event);
}

缩放函数如下

void RectItem::ResizeRect(const QPointF &mousePos)
{
    // 当前无操作,直接返回
    if(m_eMouseHandle == Mouse_None)
    {
        return;
    }

    // 准备变化
    this->prepareGeometryChange();

    QRectF rect = m_rect;
    qreal dMouseX = mousePos.x();   // 鼠标当前的y坐标
    qreal dMouseY = mousePos.y();   // 鼠标当前的y坐标
    const qreal dMixSize = 2.0 * (1 + m_dAdjust);   // 收缩时的最小尺寸
    // 当前剩余的高度和宽度
    double dRemainWidth = m_pressRect.width();
    double dRemainHeight = m_pressRect.height();

    if(m_eMouseHandle == Mouse_LeftTop || m_eMouseHandle == Mouse_MiddleLeft || m_eMouseHandle == Mouse_MiddleTop)    // 鼠标在左上、左、上
    {   // 右下角的点保持不变

        // 向上拉伸缩放宽度是不变的
        if(m_eMouseHandle != Mouse_MiddleTop)
        {
            // 剩余宽度=矩形右边x坐标-鼠标移动当前x
            dRemainWidth = m_pressRect.right() - dMouseX;
            if(dRemainWidth < dMixSize)
            {
                dRemainWidth = dMixSize;
            }
        }

        // 向左拉伸缩放高度是不变的
        if(m_eMouseHandle != Mouse_MiddleLeft)
        {
            // 剩余高度=矩形底部y-鼠标移动当前y
            dRemainHeight = m_pressRect.bottom() - dMouseY;
            if(dRemainHeight < dMixSize)
            {
                dRemainHeight = dMixSize;
            }
        }

        // 如果宽度或者高度缩放到最小值,则不让再缩放了
        if(dRemainWidth > dMixSize && dRemainHeight > dMixSize)
        {
            // 计算左上角的坐标
            rect.setTopLeft(QPointF(m_pressRect.right() - dRemainWidth, m_pressRect.bottom() - dRemainHeight));
        }
    }
    else if(m_eMouseHandle == Mouse_LeftBottom || m_eMouseHandle == Mouse_MiddleBottom)   // 鼠标在左下、下
    {   // 保持右上角不变

        // 向下拉伸缩放宽度是不变的
        if(m_eMouseHandle != Mouse_MiddleBottom)
        {
            // 剩余宽度=矩形右边x坐标-鼠标移动当前x
            dRemainWidth = m_pressRect.right() - dMouseX;
            if(dRemainWidth < dMixSize)
            {
                dRemainWidth = dMixSize;
            }
        }

        // 剩余高度=矩形底部y-鼠标移动当前y
        dRemainHeight = dMouseY - m_pressRect.top();
        if(dRemainHeight < dMixSize)
        {
            dRemainHeight = dMixSize;
        }

        // 如果宽度或者高度缩放到最小值,则不让再缩放了
        if(dRemainWidth > dMixSize && dRemainHeight > dMixSize)
        {
            // 计算左下角的坐标
            rect.setBottomLeft(QPointF(m_pressRect.right() - dRemainWidth, m_pressRect.top() + dRemainHeight));
        }
    }
    else if(m_eMouseHandle == Mouse_RightBottom || m_eMouseHandle == Mouse_MiddleRight)   // 鼠标在右下、右
    {   // 保持左上角落不变

        // 剩余宽度=鼠标移动当前x坐标-矩形左边x坐标
        dRemainWidth = dMouseX - m_pressRect.left();
        if(dRemainWidth < dMixSize)
        {
            dRemainWidth = dMixSize;
        }

        // 向右拉伸缩放高度是不变的
        if(m_eMouseHandle != Mouse_MiddleRight)
        {
            // 剩余高度=矩形底部y-鼠标移动当前y
            dRemainHeight = dMouseY - m_pressRect.top();
            if(dRemainHeight < dMixSize)
            {
                dRemainHeight = dMixSize;
            }
        }

        // 如果宽度或者高度缩放到最小值,则不让再缩放了
        if(dRemainWidth > dMixSize && dRemainHeight > dMixSize)
        {
            // 计算右下角的坐标
            rect.setBottomRight(QPointF(m_pressRect.left() + dRemainWidth, m_pressRect.top() + dRemainHeight));
        }
    }
    else if(m_eMouseHandle == Mouse_RightTop)   // 右上
    {   // 保持左下角不变

        // 剩余宽度=矩形右边x坐标-鼠标移动当前x
        dRemainWidth = dMouseX - m_pressRect.left();
        if(dRemainWidth < dMixSize)
        {
            dRemainWidth = dMixSize;
        }

        // 剩余高度=矩形底部y-鼠标移动当前y
        dRemainHeight = m_pressRect.bottom() - dMouseY;
        if(dRemainHeight < dMixSize)
        {
            dRemainHeight = dMixSize;
        }

        // 如果宽度或者高度缩放到最小值,则不让再缩放了
        if(dRemainWidth >= dMixSize && dRemainHeight >= dMixSize)
        {
            // 计算右上角的坐标
            rect.setTopRight(QPointF(m_pressRect.left() + dRemainWidth, m_pressRect.bottom() - dRemainHeight));
        }
    }


    this->setRect(rect);
}

总结

该章简单讲解了一下如何拖动图元进行缩放,下章将继续讲解如果拖动旋转图元

整个工程 示例源码 下载文章来源地址https://www.toymoban.com/news/detail-502114.html

到了这里,关于QGraphicsItem鼠标拖动图元进行缩放拉伸(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包