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

简介: 关于 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);
}

 


相关文章
|
2月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
101 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
2月前
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
126 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
WK
|
7天前
|
开发框架 开发工具 C++
C++跨平台框架Qt
Qt是一个功能强大的C++跨平台应用程序开发框架,支持Windows、macOS、Linux、Android和iOS等操作系统。它提供了250多个C++类,涵盖GUI设计、数据库操作、网络编程等功能。Qt的核心特点是跨平台性、丰富的类库、信号与槽机制,以及良好的文档和社区支持。Qt Creator是其官方IDE,提供了一整套开发工具,方便创建、编译、调试和运行应用程序。Qt适用于桌面、嵌入式和移动应用开发。
WK
25 5
|
1月前
(14)Qt绘图(one)
本文介绍了在Qt中使用QPainter进行绘图的基础操作,包括如何指定绘图设备、使用QPen和QBrush设置线条和填充样式、绘制不同样式的线条和形状,以及如何实现纹理填充和渐变填充等效果。
56 6
(14)Qt绘图(one)
|
1月前
|
计算机视觉
(15)Qt绘图(two)
Qt框架中QPainter类的多种绘图功能,包括坐标变换、基本图形绘制、文本和图片绘制、图像保存以及碰撞检测等。
38 1
(15)Qt绘图(two)
|
2月前
|
计算机视觉
基于QT的opencv插件框架qtCvFrameLearn实战
这篇文章详细介绍了如何基于Qt框架开发一个名为qtCvFrameLearn的OpenCV插件,包括项目配置、插件加载、Qt与OpenCV图像转换,以及通过各个插件学习OpenCV函数的使用,如仿射变换、卡通效果、腐蚀、旋转和锐化等。
44 10
|
2月前
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
QT多插件通信框架CTK编译记录
|
4月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
178 1
Qt(C++)开发一款图片防盗用水印制作小工具
|
3月前
|
监控 C++ 容器
【qt】MDI多文档界面开发
【qt】MDI多文档界面开发
87 0
|
2月前
|
开发工具 C++
qt开发技巧与三个问题点
本文介绍了三个Qt开发中的常见问题及其解决方法,并提供了一些实用的开发技巧。