143-QPainter和Graphics/View绘图-Graphics/View绘图- Graphics/View绘图框架介绍

Graphics/View绘图框架介绍

Graphics/View 绘图框架类似于前面介绍的Model/View 机制。

Graphics 指QGraphicsScene(场景)类,它是不可见的,相当于一个容器,在它里面放置各种图项(QGraphicsItem)并对放置的图项进行管理;

View 指QGraphicsView 控件,QGraphicsScene 中的绘图项通过 QGraphicsView 控件显示出来,同一个 QGraphicsScene可以用多个QGraphicsView 显示

Graphics/View 框架结构主要包含三个主要的类:QGraphicsScene QGraphicsView和各种QGraphicsItem。QGraphicsScene(场景)本身不可见,但又是存储和管理2D图项的容器,场景没有自己的视觉外观,只负责管理图项,必须通过与之相连的 QGraphicsView 控件来显示图项及与外界进行交互操作。QGraphicsScene主要提供图项的操作接口,传递事件和管理各个图项的状态,提供无变换的绘制功能(如打印)。QGraphicsView 提供一个可视的窗口,用于显示场景中的图项。QGraphicsItem是场景中图项的基类图项有自定义的图项(继承自QGraphicsItem 的子类),还有标准的图项,例如矩形(QGraphicsRectItem)多边形(QGraphicsPolygonItem)、椭圆(QGraphicsEllipseItem)、路径(QGraphicsPathItem)线条(GraphicsLineltem)和文本(QGraphicsTextItem)等。读者可以把 QGraphicsScene理解成电影胶卷,把QGraphicsView 理解成电影放映机,而把图项理解成电影胶卷中的人物、树木、建筑物等。

QPainter采用面向过程的描述方式绘图,而 Graphics/View 采用面向对象的描述方式绘图。Graphics/View 框架中的每一个图项都是一个独立的元素,可以对图项进行操作,图项支持鼠标操作,可以对图项进行按下、移动、释放、双击、滚轮滚动和右键菜单操作,还支持键盘输人和拖放操作。Grphics/View 绘图时首先创建一个场景,然后创建图项对象(如直线对象、矩形对象),再使用场景的 add()丽数,将图项对象添加到场景中,最后通过视图控件进行显示。对于复杂的图像来说,如果其中包含大量的直线、曲线、多边形等对象,管理图项对象比管理 QPainter 的绘制过程语句要容易,并且图项对象更符合面向对象的思想,图形的重复使用性更好。

Graphics/View坐标系

Graphics/View 坐标系基于笛卡儿坐标系,图项在场景中的位置和几何形状通过 x坐标和y坐标表示。当使用没有变换的视图观察场景时,场景中的一个单位对应屏幕上的一个像素。
Graphics/View 架构中有三种坐标系统,分别是图项坐标、场景坐标和视图坐标。场景坐标类似于 QPainter 的逻辑坐标,一般以场景的中心为原点;视图标是窗口界面的物理坐标,其左上角为坐标原点,图项坐标是局部逻辑坐标,通常以图项的中心为原点。Graphics/View 提供了三个坐标系统之间的转换函数。

图项坐标、场景坐标和视图坐标

图项存在于自己的本地坐标上,图项的坐标系通常以图项中心为原点,图项中心也是所有坐标变换的原点,图项坐标方向是 x轴正方向向右,y 轴正方向向下。

创建自定义图项时,需要注意图项的坐标,QGraphicsScene 和 QGraphicsView 会完成所有的变换。

  • 例如,如果接收到一个鼠标按下或拖人事件,所给的事件位置是基于图项坐标系的。如果某个点位于图项内部,使用图项上的点作为 QGraphicsItem.contains()虚函数的参数,函数会返回True。类似地,图项的边界矩形和形状也基于图项坐标系。
  • 图项的位置是图项的中心点在其父图项坐标系统的坐标,场景可以理解成顶层图项,子图项的坐标与父图项的坐标相关,如果子图项无变换,则子图项坐标和父图项坐标之间的区别与它们的父图项的坐标相同。例如,如果一个无变换的子图项精确地位于父图项的中心点,则父子图项的坐标系统是相同的。
  • 如果子图项的位置是(100,0),子图项上的点(0,100)就是父图项上的点(100,100)。即使图项的位置和变换与父图项相关,子图项的坐标也不会被父图项的变换影响,虽然父图项的变换会隐式地变换子图项。例如,即使父图项被翻转和缩放,子图项上的点(0,100)仍旧是父图项上的点(100,100)。
  • 如果调用QGraphicsItem类的 paint()函数重绘图项,应以图项坐标系为基准场景坐标是所有图项的基础坐标系统。场景坐标系统描述了顶层图项的位置,并且构成从视图到场景的所有场景事件的基础。每个图项在场景上都有场景坐标和边界矩形。场景坐标的原点在场景中心,坐标方向是x轴正方向向右,轴正方向向下。视图坐标是窗口控件的坐标,视图坐标的单位是像素,QGraphicsView 的左上角是(00)。所有鼠标事件、拖拽事件最开始都使用视图坐标,为了和图项交瓦,需要转换为场景坐标。
坐标变换函数

在Graphics/View框架中,经常需要在不同种坐标间进行变换:从视图到场景,从场景到图项,从图项到图项。Graphics/View 框架中的坐标变换函数如下

  • QGraphicsView.mapToScene()视图到场景
  • QGraphicsView.mapFromScene()场景到视图
  • QGraphicsItemmapFromScene()场景到图项
  • QGraphicsItem.mapToScene()图项到场景
  • QGraphicsItem.mapToParent()子图项到父图项
  • QGraphicsItem.mapFromParent()父图项到子图项
  • QGraphicsItem.mapToItem()本图项到其他图项
  • QGraphicsItem,mapFromItem()其他图项到本图项

在场景中处理图项时,经常需要在场景到图项、图项到图项、视图到场景间进行坐标和图形转换。

  • 当在 QGraphicsView 的视口中单击鼠标时,应该通过调用QGraphicsView.mapToScence()与 QGraphicsScene,itemAt()函数来获知光标下是场景中的哪个图项;
  • 如果想获知一个图项在视口中的位置,应该先在图项上调用QGraphicsItemmapToScene()函数,然后调用QGraphicsView,mapFromScene()函数;
  • 如果想获知在一个视图中有哪些图项,应该把 QPainterPath 传递到 mapToScene()函数,然后再把映射后的路径传递到QGraphicsScene,items()函数。
  • 可以调用QGraphicsItem,mapToScene()函数与QGraphicsItem,mapFromScene()函数在图项与场景之间进行坐标与形状的映射,也可以在子图项与其父图项之间通过QGraphicsItem,mapToParent()与QGraphicsItem.mapFromItem()函数进行映射。
  • 所有映射函数可以包括点、矩形、多边形路径。视图与场景之间的映射也与此类似。对于视图与图项之间的映射,应该先从视图映射到场景,然后再从场景映射到图项。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值