关于 Qt图形视图框架自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞 的解决方法

问题

        自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞 

 

示意图

 

解决后的目标效果

 

解决方法

        变换之前或之后一定要调用一次prepareGeometryChange();

void RectItemBase::stretchByPoint(QPointF originPointF, QPointF fromPointF, QPointF toPointF)
{
    qreal stretchX = 1.0;
    qreal stretchY = 1.0;
    QPointF originPointFTemp;
    QPointF fromPointFTemp;
    QPointF toPointFTemp;

    // 步骤一:获取中心点与右领边的旋转角度(逆时钟为正)
    qreal angleOffset;
    QPointF anglePointF;
    if(originPointF == _originLeftTopPointF)
    {
        anglePointF = _originRightTopPointF;
    }else if(originPointF == _originLeftBottomPointF)
    {
        anglePointF = _originLeftTopPointF;
    }else if(originPointF == _originRightBottomPointF)
    {
        anglePointF = _originLeftBottomPointF;
    }else if(originPointF == _originRightTopPointF)
    {
        anglePointF = _originRightBottomPointF;
    }
    angleOffset = MyMath::lineReverseClockAngle(originPointF, anglePointF);
    // 步骤二:已对称点先旋转正
    QTransform transform;
    transform.translate(originPointF.x(), originPointF.y());
    transform.rotate(angleOffset);
    originPointFTemp = transform.map(originPointF-originPointF) - originPointF;
    fromPointFTemp = transform.map(fromPointF-originPointF)-originPointF;
    toPointFTemp = transform.map(toPointF-originPointF)-originPointF;
    // 步骤三:获取角度查的缩放比,得到旋转对其后的原始高宽和拉伸后的宽高
    qreal distanceOrigin2From = MyMath::lineDistance(originPointF, fromPointF);
    qreal distanceOrigin2To = MyMath::lineDistance(originPointF, toPointF);
    qreal angleOrigin2From = MyMath::lineReverseClockAngle(originPointF, fromPointF);
    qreal angleOrigin2To = MyMath::lineReverseClockAngle(originPointF, toPointF);
    qreal angleFrom2Origin2AdjacentSide = angleOrigin2From - angleOffset;
    qreal angleTo2Origin2AdjacentSide = angleOrigin2To - angleOffset;
    qreal originWidth = distanceOrigin2From * qCos(qDegreesToRadians(angleFrom2Origin2AdjacentSide));
    qreal originHeight = distanceOrigin2From * qSin(qDegreesToRadians(angleFrom2Origin2AdjacentSide));
    qreal width = distanceOrigin2To * qCos(qDegreesToRadians(angleTo2Origin2AdjacentSide));
    qreal height = distanceOrigin2To * qSin(qDegreesToRadians(angleTo2Origin2AdjacentSide));
#if 0
    qDebug() << __FILE__ << __LINE__ << originPointF << fromPointF
             << "原来距离:" << distanceOrigin2From << "原来夹角:" << angleOrigin2From << "与逆时针邻边夹角:" << angleFrom2Origin2AdjacentSide
             << "原始宽度:" << originWidth << "原始高度:" << originHeight;
    qDebug() << __FILE__ << __LINE__ << fromPointFTemp << toPointFTemp
             << "现在距离:" << distanceOrigin2To << "现在夹角:" << angleOrigin2To << "与逆时针邻边夹角:" << angleTo2Origin2AdjacentSide
             << "现在宽度:" << width << "现在高度:" << height;
#endif
    // 步骤四:限制最小宽度和高度
    if(qAbs(width) < _minWidth)
    {
        width = _minWidth;
        if(width < 0)
        {
            width = -_minWidth;
        }else{
            width = _minWidth;
        }
    }
    if(qAbs(height) < _minHeigt)
    {
        if(height < 0)
        {
            height = -_minHeigt;
        }else{
            height = _minHeigt;
        }
    }
    // 限制不能反向
    if(originWidth > 0 && width < 0)
    {
        width = _minWidth;
    }else if(originWidth < 0 && width > 0)
    {
        width = -_minWidth;
    }
    if(originHeight > 0 && height < 0)
    {
        height = _minWidth;
    }else if(originHeight < 0 && height > 0)
    {
        height = -_minWidth;
    }
    stretchX = width / originWidth;
    stretchY = height / originHeight;
    // 步骤五:缩放
    transform.scale(stretchX, stretchY);
    // 步骤六:变换回原来的角度
    transform.rotate(-angleOffset);
    // 一定要调用prepareGeometryChange(),否则无法更新变换后的区域
    prepareGeometryChange();
    // 步骤七:变换坐标
    _leftTopPointF = transform.map(_originLeftTopPointF- originPointF);
    _leftBottomPointF = transform.map(_originLeftBottomPointF - originPointF);
    _rightTopPointF = transform.map(_originRightTopPointF - originPointF);
    _rightBottomPointF = transform.map(_originRightBottomPointF - originPointF);
}

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值