【Qt】一文总结图形视图框架基础

一、Graphics View框架结构特点

(1)在Graphics View框架结构中,可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。
(2)Graphics View支持事件传播体系结构,可以使用图元在场景(Scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标事件。
(3)在Graphics View框架中,通过二元空间划分树(Binary Space partitioning,BSP)提供快速的图元查找,能够实时地显示包含上百万个图元的大场景。

二、图形视图框架的结构

图形视图框架包括场景(Scene)、视图(View)、图形项(GraphicsItem)三部分。三部分用QGraphicsScene、QGraphicsView和QGraphicsItem三个类来表示。
(1)场景类:QGraphicsScene类
QGraphicsScene是一个放置图元的容器,是图形视图框架中的场景,拥有以下功能:

1、提供用于管理大量图形项(Items)的便捷接口。
2、分发事件给场景中的每一个图形项。
3、管理图形项(items)的状态,例如:选择和焦点处理等。
4、提供无变换的渲染功能,主要用于打印。

场景是图形项QGraphicsItem对象的容器。调用QGraphicsScene::addItem()函数将图形项(Items)添加到场景中,然后调用众多的图形项查找函数来检索添加的图形项。
QGraphicsScene::items()函数和几个重载函数可以返回符合条件的所有图形项,这些图形项不是与指定的点、矩形、多边形或者矢量路径相交,就是包含在它们之中。
QGraphicsScene::itemAt()函数返回指定点的最上面的图形项(场景中的图形项可能会重叠)。所有的图形项寻找函数返回的图形项都是按照递减顺序进行的(例如第一个返回的图形项在最上面,最后返回的图形项在最下面)。
如果要从场景中删除一个图形项,可以使用QGraphicsScene::RemoveItem()函数。
场景允许通过QGraphicsScence::render()函数将场景的各个部分呈现到一个绘制设备中。

(1)视图类:QGraphicsView类
用于显示场景中的图元
QGraphicsView提供了视图widget,用来显示场景中的内容。可以将多个视图连接到同一个场景来为相同的数据集提供多个视口。
QGraphicsView是一个可滚动的区域控件,提供了一个滚动条来浏览大的场景,可以使用setDragMode()函数以QGraphicsView::ScrollHandDrag为参数来使光标变为手掌形状,从而可以拖动场景。如果设置setDragMode()的参数为QGraphicsView::RubberBandDrag,那么可以在视图上使用鼠标拖出橡皮筋框来选择图形项。

视图从键盘和鼠标接收输入事件,并将其转换成场景事件(在适当的地方将使用的坐标转换为场景坐标),然后将事件发送到可视化场景。

使用QGraphicsView::transform(),视图可以转换场景的坐标系统。同样提供了转换视图和场景坐标的功能:QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()。

默认的QGraphicsView提供了一个QWidget作为视口部件,如果要使用OpenGL进行渲染,可以调用QGraphicsView::setViewport()设置QGLWidget作为视口。QGraphicsView会获取视口部件的拥有权(ownership)。

(2)图元类:QGraphicsItem类
QGraphicsItem是场景中图形项的基类。图形视图框架为常见的典型形状提供了标准的图形项,例如:矩形(QGraphicsRectIem)、椭圆(QGraphicsEllipseItem)和文本项(QGraphicsTextItem)等。不过,只有当编写自定义图形项时才能发挥QGraphicsItem的强大功能。QGraphicsItem主要支持如下功能:

1、鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件
2、键盘输入焦点和键盘事件
3、拖放事件
4、分组,使用QGraphicsItemGroup通过parent-child关系来实现
5、碰撞检测

除此之外,图形项还可以存储自定义的数据,可以使用setData()进行数据存储,然后使用data()获取其中的数据。
一个场景分为三层:图形项层(ItemLayer)、前景层(ForegroundLayer)和背景层(BackgroundLayer)。场景的绘制总是从背景层开始,然后是图形项层,最后是前景层。前景层和背景层都可以使用QBrush进行填充,比如使用渐变和贴图等。这里的前景色设置为了半透明的白色,当然也可以设置为其他的填充。

三、图形视图框架的坐标系统

图形视图是基于笛卡尔坐标系统的。
三个图形视图框架的基本类有各自不同的坐标系:场景坐标、视图坐标和图元坐标。
在渲染时,图形视图的场景坐标对应于QPainter的逻辑坐标,视图坐标与设备坐标相同。

(3-1)场景坐标

场景坐标是所有图元的基础坐标系统。场景坐标的原点在场景中心。QGraphicsScene类的坐标系以中心为原点(0,0)。
场景中的每个项目都有一个场景位置和边界矩形(QGraphicsItem::scenePos(),QGraphicsItem::sceneBoundingRect())。此外还有它的本地项目pos和边界矩形。场景位置描述了项目在场景坐标中的位置,其场景边界矩形构成了QGraphicsScene如何确定场景中哪些区域发生了变化的基础。场景中的变化通过QGraphicsScene::changed()信号进行通信,参数为场景矩形列表。

(3-2)视图坐标

视图坐标是窗口部件的坐标。视图坐标的单位是像素。QGraphicsView视图的左上角是(0,0)。QGraphicsView类继承自Qwidget类,所以该类以窗口的左上角作为自己坐标系的原点。QGraphicsView的viewport的左上角总是(0,0),而右下角总是(viewport.width,viewport height)。所有鼠标事件和拖放事件最开始时都是作为视图坐标接收,在使用中需要将这些坐标映射到场景以与图元交互。

(3-3)图元坐标

图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点。
在创建自定义图形项(Item)时,我们只需要关心图元坐标。
在这里插入图片描述

四、类关系

在这里插入图片描述

五、类图

(5-1)图形效果类图

在这里插入图片描述

(5-2)图形布局类图

在这里插入图片描述

(5-3)图形项类图

在这里插入图片描述

六、图形视图框架的事件处理与传播

图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景传递给相应的图形项。即:

视图——>场景——>图形项

(1)对于键盘事件,它会传递给获得焦点的图形项,可以使用QGraphicsScene类的setFocusItem()函数或者图形项自身调用setFocus()函数来将其设置为焦点图形项。默认情况下,如果场景没有获得焦点,那么所有的键盘事件都会被丢弃。如果调用了场景的setFocus()函数或者场景中的一个图形项获得了焦点,那么场景也会自动获得焦点。

(2)对于鼠标悬停效果,QGraphicsScene会调度悬停事件。如果一个图形项可以接收悬停事件,那么当鼠标进入它的区域之中时,它就会收到一个GraphicsSceneHoverEnter事件。如果鼠标继续在图形项的区域之中进行移动,那么QGraphicsScene就会向该图形项发送GraphicsSceneHoverMove事件。当鼠标离开图形项的区域时,它将会收到一个GraphicsSceneHoverLeave事件。图形项默认是无法接收悬停事件的,可以使用QGraphicsItem类的setAcceptHoverEvents()函数设置图形项接收鼠标悬停事件。

七、总结

文本总结了Qt中的图形视图框架的基础知识,包括常用类、类图关系、图形视图框架的图标系统以及图形视图框架的事件处理和传播。


搜索关注【嵌入式小生】wx公众号获取更多精彩内容。
请添加图片描述

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

iriczhao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值