请教大家一个QGraphicsItem 坐标变换的问题.

firebolt2002 2015-06-07 05:52:00
大家好,最近需要用Qt Graphicsview 框架写一个做图工具,需要实现通过鼠标创建线、矩形、圆、多边形等几何图形,并完成一些基本的几何变换,如,移动,改变大小,旋转,组合等操作。QGraphicsView 、QGraphicsScene、QGraphicsItem本身支持几何图形的移动、旋转等操作,但是没有提供改变大小的接口。
用QAbstractGraphicsShapeItem 类做基类,派生出一些基本几何图形类,并给它们添加用于鼠标操作的控制点,这些都没有问题。但是加入旋转变换后问题出现了。
首先QGraphicsItem的本地坐标系统,如果该坐标的中心点不是该图形的中心,那么这个图形在旋转后,进行改变大小的操作,然后再旋转,transformOriginPoint()没有办法进行调整,或者说我怎么也调整不对。目前解决的办法就是强制本地坐标的原点在图形的中心位置,这样做的结果是调整大小的时候图形是等比例调整的,虽然别扭但也能用。
但是在做Group的时候又遇到新问题了,就是QGraphicsItem 的 pos() 没有办法设置到组合的中心,希望对这方面有了解的朋友能帮忙讲解一下。

图中 绿色的圆点为 transformOriginPoint , 蓝色圆点为当前pos();




测试程序代码也附上:
http://download.csdn.net/detail/firebolt2002/8781985
...全文
1548 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_23029893 2016-03-04
  • 打赏
  • 举报
回复
谢谢LZ分享,有些问题想请教下,已私信
firebolt2002 2015-06-12
  • 打赏
  • 举报
回复
关于坐标的问题我已经解决了,问题的结症主要在于ITEM本地坐标重建的问题,Item的本地坐标应该始终保持圆点在坐标系中心的位置,本身QGraphicsItem没有考虑改变大小的问题,所以改变大小后,本地坐标系也被破坏了。解决问题的方法也挺简单,就是改变大小后重建一下本地坐标系统。
    
    QPointF pt1,pt2,delta;
    pt1 = mapToScene(transformOriginPoint());
    pt2 = mapToScene(boundingRect().center());
    delta = pt1 - pt2;

    setTransform(transform().translate(delta.x(),delta.y()));
    setTransformOriginPoint(boundingRect().center());
    setTransform(transform().translate(-delta.x(),-delta.y()));
    moveBy(-delta.x(),-delta.y());
希望对碰到同样问题的朋友有帮助。
top_worker 2015-06-11
  • 打赏
  • 举报
回复
我也很想了解,mark下。
firebolt2002 2015-06-11
  • 打赏
  • 举报
回复
引用 5 楼 top_worker 的回复:
我也很想了解,mark下。
我发现每次旋转后,QGraphicsItem的本地坐标系也跟着旋转了,然后如果改变图元的大小(通过鼠标拖动控制点),QGraphicsItem的坐标系就彻底对不上号了。
firebolt2002 2015-06-10
  • 打赏
  • 举报
回复
引用 3 楼 rjsloth 的回复:
是否可以考虑用QPainterPath和QGraphicsWidget来实现你这个工具? ....
用什么方式实现都是可以的,问题是我想搞明白QGraphicsView框架是怎么运行的。
rjsloth 2015-06-10
  • 打赏
  • 举报
回复
是否可以考虑用QPainterPath和QGraphicsWidget来实现你这个工具? 我觉得这个工具必须解决的基本问题有三个:一是将图形数据存放到磁盘,这需要表示各种形状的数据结构,自己实现;二是描述形状的数据结构(推荐用QPainterPath);三是显示图形的数据结构,用QGraphicsWidget(或者你愿意用QAbstractGraphicsShapeItem也行)。 这三个问题中,核心在于第二个问题,之所以推荐使用QPainterPath,是因为这个类基本上可以很方便的描述所有常用的形状以及各种形状的组合,这样就不用自己实现了,省了大量时间。虽然不能描述缩放和旋转,但实际上这里不需要描述缩放和旋转,缩放和旋转只需要记录在问题一的数据结构中并用于指导显示时描绘即可。 第一个问题,我觉得当前你记录形状用的数据,抛开缩放、旋转和位移,肯定可以使用QPainterPath描述。 第三个问题,由于在使用QPainter描绘QPainterPath的时候可以自由旋转、缩放、调整位置,所以肯定可以得到想要描绘的结果。 这样,QPainterPath是矢量图形;记录形状用的数据结构在矢量图形的基础上,记录缩放和旋转信息,并指导QPainter描绘包含旋转、位移和缩放信息的图像。一个实现你需要的工具的框架就有了。 我自己没有实现,只是从理论上说一下,但我的方法应该是方便可行的。如果觉得我的方法不行,可以提出否认和疑问:)
firebolt2002 2015-06-07
  • 打赏
  • 举报
回复
原来的代码删了,修改好的传上去了。 希望对需要的人有帮助。 http://download.csdn.net/detail/firebolt2002/8782273
firebolt2002 2015-06-07
  • 打赏
  • 举报
回复
问题解决了,原点的问题解决了。 QPointF delta = pos() - bound.center() ; // 将本地坐标原点移动到中心, setTransform(transform().translate(delta.x(),delta.y())); //设置原点 setTransformOriginPoint( bound.center()); //还原图形的位置. moveBy(-delta.x(),-delta.y()); m_group->setTransformOriginPoint(bound.center()); group的问题解决了,希望其他问题也能解决掉。

16,249

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧