目的:

对于刚了解QGraphics体系来说,基于QGraphicsView实现白板绘画曲线实现矢量绘画其实不难,然后基于非矢量绘画(通过绘画图片QImage)时,看了源代码后,结合经理所说方法,遇到两个问题,并被这两个问题弄蒙了,特意整理。
1、QPainter 不同。
1.1 自定义的图元(QGraphicsItem)中重写的paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)中QPainter主要是负责重新绘画Item(然后在item上绘画图片)。
1.2 item中QPainter painter(&m_pCanvas)主要是负责在画布(QImage上)绘画。

2、QImage地方用法错误。
2.1 QImage应该在自定义的图元中作为item,单独用重写paint()与boundingRect(),这个函数分别用来实现绘画item(重绘画Image)以及返回item的Rect。而不是自定义的在Scene使用。
2.2 QImage作为绘画的item,应该设置大小,虽然可能不报错,但是可能没法绘画具体Image。

总结:

对于要实现自定义的图元,我们必须重写paint()与boundingRect()这两个函数。这两个用来绘画你所需要的图元,以及图元碰撞坚持,边界设置。如上本质就是绘画图片图元,由于图片特殊性(继承自QPaintDevice),在图片图元上我们可以利用QPainter进行绘画,然后只需对图元paint()即可。同理其它QPainter安原理来说,也可以,但是性能不一样。

参考网址:https://blog.51cto.com/9291927/1879128

注意点

1、注意绘画曲线不能简单绘画直线、也不是简单点连线,否则容易绘画曲线有折线、容易间断画点。而应该采取相关算法(如贝尔斯曲线)进行曲线绘制。
2、明白QGraphicsView体系架构,明白QGraphicsView、QGraphicsScene、QGraphicsItem三者之间职责。

QGraphicsScene:

1、场景作为QGraphicsItem对象的容器,能对图元(自定义也可以)进行管理,为管理大量的items提供一个快速的接口。
2、传播事件(鼠标事件、键盘事件等)每个item。
3、管理item的状态,例如选择,焦点处理。 提供未经变换的渲染功能,主要用于打印。

QGraphicsView:

1、提供可视化场景、多个View可以监控同一个场景。
2、接受鼠标、键盘、resize等传来的事件,并传播给场景。

QGraphicsItem:

1、所有图元的父类、可以自定义图元。
2、QGraphicsItem支持以下特性: 鼠标按、移动、释放、双击事件,鼠标悬停事件,滚轮事件,弹出菜单事件。
3、父子关系(QGroup)
4、碰撞检测

3、体系之间坐标关系view scene item 三者之间坐标关系、事件传递顺序。

事件传递顺序:View->Scene->item

(如果item不能接受到鼠标事件)
可以考虑要设置(this->setAcceptedMouseButtons(Qt::LeftButton);
setFlag(QGraphicsItem::ItemIsSelectable);

三者之间坐标关系:

这个问题整理主要是因为,当时我直接在Item获取scenePos()好像总返回OPoint(0,0);然后整理这个问题,并梳理三者之间关系。

问题:

QGraphicsItem::scenePos() 总是返回QPointF(0,0)?
希望通过item的scenePos方法获得item在scene中的位置,结果总是返回(0,0)。
首先要搞清楚,在QT的Graphics中存在三个坐标系:item coordinates、scene coordinates、view coordinates。

item coordinates(图元坐标)

图元存在于自己的本地坐标上,图元的坐标系统通常以图元中心为原点,图元中心也是所有坐标变换的原点,图元坐标方向是x轴正方向向右,y轴正方向向下。创建自定义图元时,只需要注意图元的坐标,QGraphicsScene和QGraphicsView会完成所有的变换。 例如,如果接受到一个鼠标按下或拖入事件,所给的事件位置是基于图元坐标系的。如果某个点位于图元内部,使用图元上的点作为QGraphicsItem::contains()虚函数的参数,函数会返回true。类似,图元的边界矩形和形状也是基于图元坐标系。


图元的位置是图元的中心点在其父图元坐标系统的坐标。按这种说法,场景是所有无父图元的图元的父图元。顶层图元的位置是场景坐标。
子图元的坐标与父图元的坐标相关。如果子图元无变换,子图元坐标和父图元坐标之间的区别与他们的父图元的坐标相同。例如,如果一个无变换的子图元精确的位于父图元的中心点,父子图元的坐标系统是相同的。如果子图元的位置是(10,0),子图元上的点(0,10)就是父图元上的点(10,10)。

由于图元的位置和变换与父图元相关,但子图元的坐标并不会被父图元的变换影响,虽然父图元的变换会隐式地变换子图元。在上例中,即使父图元被翻转和缩放,子图元上的点(0,10)仍旧是父图元上的点(10,10)。

如果调用QGraphicsItem类的paint()函数重绘图元时,则以图元坐标系为基准。

scene coordinates(场景坐标)
场景坐标是所有图元的基础坐标系统。场景坐标系统描述了顶层图元的位置,并且构成从视图传播到场景的所有场景事件的基础。每个图元在场景上都有场景坐标和边界矩形。场景坐标的原点在场景中心,坐标原点是X轴正方向向右,Y轴正方向向下。


View coordinates (视图坐标 )
视图坐标是窗口部件的坐标,视图坐标的单位是像素,QGraphicsView的左上角是(0,0)。所有鼠标事件、拖拽事件最开始都使用视图坐标,为了和图元交互,需要转换坐标为场景坐标。

QGraphicsItem::pos() 指的是在父图元坐标下item位置
Returns the position of the item in parent coordinates. If the item has no parent, its position is given in scene coordinates.
The position of the item describes its origin (local coordinate (0, 0)) in parent coordinates; this function returns the same as mapToParent(0, 0).
QGraphicsItem::scenePos() 指的是在item在场景中位置
Returns the item’s position in scene coordinates. This is equivalent to calling mapToScene(0, 0).

基于QGraphicsView实现绘画曲线注意点相关推荐

  1. QGraphicsView绘画曲线注意点(二)

    目的: 整理基于QGraphicsView体系实现白板绘画曲线注意项,偏于细节方面,但是也是较为高效的方法. 注意点: 1.注意绘画曲线时,其中item可以分两种思路进行,一种是以矢量方式,另一种是以 ...

  2. 基于移动最小二乘法的曲线曲面拟合论文阅读笔记

    基于移动最小二乘法的曲线曲面拟合论文阅读笔记 论文地址:http://www.cnki.com.cn/Article/CJFDTotal-GCTX200401016.htm 一.Problem Sta ...

  3. 基于QGraphicsView的简易画板EasyCanvas -- 第一版

    最近使用 QGraphicsView 做了个简易的画板 EasyCanvas ,界面效果如下: 具有如下功能: 画布设置 图元添加和修改 保存为图片 第二版已更新 基于QGraphicsView的简易 ...

  4. 基于Labview的双函数曲线

    一.功能描述 已知两个函数:Y=X(1+iN)和Y=X(1+i)N,X为初始值,i为变化率,N表示次数(N从为 1-20 之间的数).要求使用 XY 图绘制出两者随次数增加的变化曲线. 二.资源获取 ...

  5. 基于python绘制ROC曲线

    基于python绘制ROC曲线,直接附代码: from sklearn.metrics import roc_curve, auc from sklearn.model_selection impor ...

  6. 基于移动最小二乘法的曲线曲面拟合(python语言实现)

    1.移动最小二乘法 上篇论文采用最小二乘法来拟合曲线,如果离散数据量比较大,形状复杂,还需要分段拟合和平滑化,因此采用移动最小二乘法进行曲线拟合,可以克服上面的缺点,还具有一些优点: 移动最小二乘法与 ...

  7. 【Python_PyQtGraph 学习笔记(三)】基于GraphicsLayoutWidget实现显示曲线对象 鼠标位置处坐标的功能

    基于GraphicsLayoutWidget实现显示曲线对象 鼠标位置处坐标的功能 前言 在PyQtGraph的官方例程中有此功能的实现,可参考Crosshair / Mouse interactio ...

  8. R语言使用ggplot2可视化贝塞尔曲线:基于经验数据可视化贝塞尔曲线(Curved Bézier lines with empirical data)、使用curve_intersect函数计算曲线

    R语言使用ggplot2可视化贝塞尔曲线:基于经验数据可视化贝塞尔曲线(Curved Bézier lines with empirical data).使用curve_intersect函数计算曲线 ...

  9. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画

    通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程 先简单的介绍下CAShapeLayer 1,CAShapeLayer继承自CALayer,可使用CALayer的所有属 ...

最新文章

  1. 作为数据科学家,我都有哪些弱点
  2. Win 10 源码一览:0.5T 代码、400 万文件、50 万文件夹
  3. Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法
  4. oracle收集统计计划,oracle收集统计信息之analyze
  5. UART0串口编程(四):UART0串口编程之在UC/OS—II中遭遇的危机
  6. 番石榴分配器vs StringUtils
  7. 两教授吐槽:如今博士研究生的论文写作水平为何如此堪忧?
  8. c语言fopen_s的用法,fopen和fopen_s用法的比较
  9. CentOS7 修改设置静态IP和DNS
  10. 我的k8s随笔:Kubernetes部署的一些输出信息
  11. java 反射 field get方法_JAVA学习之反射getDeclaredField()方法与getField()方法的区别
  12. Odoo10教程---模块化三:模型约束,高级视图,工作流,安全性,向导,国际化和报表等
  13. JavaScript学习(七十)—函数中this的指向问题
  14. Visual Studio 2012安装VASSISTX插件后导致CPU高的解决的方法
  15. C# 搭建一个简单的WebApi项目
  16. 使用Gson解析json
  17. 史上超详细python爬取国家统计局数据
  18. mysql添加表字段脚本_mysql数据库修改字段及新增字段脚本
  19. python可视化(2-1)绘图对象(条形图、直方图、柏拉图)
  20. 《游戏大师Chris Crawford谈互动叙事》一第 6 章 数学之苦劳

热门文章

  1. 诺亚传说虚拟机 游戏总是提示:网络暂时无法连接,重启还是无法登陆.
  2. 【转】Fiddler抓包工具手机添加代理后连不上网解决办法
  3. 什么输入法对计算机英语,电脑有什输入法英语单词
  4. python简单语法2
  5. 华为交换机通过ACL限制登录telnet账户为指定IP地址
  6. 朴素系统优化思维的实践
  7. JAVA计算机毕业设计翻转课堂微视频管理系统Mybatis+系统+数据库+调试部署
  8. 小米手机读取手机短信
  9. 新浪微博AppKey大集合(share)
  10. 小程序自定义导航栏高度