编程学习
Qt学习18:图形视图框架
00 分钟
2023-8-1
2023-11-23
type
status
date
slug
summary
tags
category
icon
password
Email
💡
落絮无声春堕泪,行云有影月含羞。——吴文英《浣溪沙》
💡
文章首发于我的个人博客:欢迎大佬们来逛逛
🔆
Qt学习的项目地址源码:
Qt-code
luumodUpdated Jul 3, 2023

图形视图框架

图形视图提供了一个界面,用于管理大量定制的2D图形项并与之交互,还提供了一个视图小部件,用于可视化这些项,支持缩放和旋转。
该框架包括一个事件传播体系结构,允许对场景中的项目进行精确的双精度交互功能。项目可以处理按键事件、鼠标按下、移动、释放和双击事件,还可以跟踪鼠标移动。
GraphicsView使用BSP(二进制空间分区)树来提供非常快速的项目发现,因此,它可以实时可视化大型场景,即使有数百万个项目。

场景Scene

QGraphicsScene提供了图形视图场景。
通过以下方式可以创建一个场景
我们需要指定场景的 坐标以及 等属性,注意这四个表示场景的显示区域。
QGraphicsScene管理某些项目状态,比如项目选择焦点
你可以通过调用QGraphicsScene::setSelectionArea()来选择场景中的项目,传递一个任意形状。
调用QGraphicsScene::selectedItems()获取当前所有选中项的列表

视图View

QGraphicsView提供了视图小部件,它可视化了场景的内容
可以把场景添加到视图中。
您可以将多个视图附加到同一个场景,从而为相同的数据集提供多个视口。
当创建完成视图和场景后,可以使用场景构造函数的最后一个参数:QObject来传递一个依赖视图。
也可以使用视图的setScene来为视图设置一个场景。
最后调用 show 即可显示视图。
要记住:显示的是视图(用show方法),只不过这个视图上包含了这个场景。
为这个场景或者视图添加装饰
  • setBackgroundBrush:设置背景画刷,传递一个QBrush类型的参数
  • setForegroundBrush:设置前景画刷,前景位于最前面,因此它会覆盖背景的画刷,可以指定一个透明度,这样就会呈现一个昏暗的效果,类似于夜间模式。
首先我们加一下背景颜色:然后我们再指定一下前景色,并且设置透明度
可以看到背景色会覆盖之前的背景色,前景色会覆盖背景色。
notion image
notion image

请注意:我们即可以对场景设置上面的属性,也可以对视图设置。
如果我们对视图设置,并且如果许多视图都加载同一个场景,则会发现只有设置的视图才会显示上面的效果;
如果我们对场景设置,则所有设置该场景的视图都被显示为上面的效果。

图形项Item

QGraphicsItem是场景中图形项的基类。图形视图为典型形状提供了几个标准项,例如
  • 矩形(QGraphicsRectItem)
  • 椭圆(QGraphicsEllipseItem)
  • 文本项(QGraphicsTextItem)
但最强大的QGraphicsItem特性是在编写自定义项时可用的。除此之外,QGraphicsItem支持以下特性:
  • 鼠标按下、移动、释放和双击事件,以及鼠标悬停事件、滚轮事件和上下文菜单事件。
  • 键盘输入焦点和按键事件
  • 拖放
  • 通过父子关系和QGraphicsItemGroup进行分组
  • 碰撞检测
item存在于本地坐标系统中,像QGraphicsView一样,它还提供了许多函数来映射项目和场景之间的坐标,以及项与项之间的坐标。
同样,像QGraphicsView一样,它可以使用矩阵:QGraphicsItem::transform()转换其坐标系统。这对于旋转和缩放单个项目非常有用。
常用API:
  • QGraphicsItem::collidesWith:两个项目的碰撞检测
  • mapFrom/ToXXXX:各种坐标的映射到那些地方
  • setPos,Pos,moveBy:Item的移动操作

图形视图框架中的类

描述
QAbstractGraphicsShapeltem
所有路径图元的共同基类
QGraphicsAnchor
表示一个QGraphicsAnchorLayout中两个图元之间的anchor
QGraphicsAnchorLayout
布局可以anchor部件到图形视图中
QGraphicsEffect
所有图形特效的基类
QGraphicsEllipseltem
可以添加到QGraphicsScene的椭圆图元
QGraphicsGridLayout
图形视图中管理部件的网格布局
QGraphicsltem
QGraphicsScene中所有图元的基类
QGraphicsltemGroup
—个将图元组当做单个图元来看待的容器
QGraphicsLayout
图形视图中所有布局类的基类
QGraphicsLayoutltem
可以被继承,允许布局类管理的自定义图元
QGraphicsLineltem
可以添加到QGraphicsScene的直线图元
QGraphicsLinearLayout
图形视图中管理部件的水平或垂直布局
QGraphicsObject
所有需要信号、槽、属性的图元的基类
QGraphicsPathltem
可以添加到QGraphicsScene的路径图元
QGraphicsPixmapltem
可以添加到QGraphicsScene的图形图元
QGraphicsPolygonltem
可以添加到QGraphicsScene的多边形图元
QGraphicsProxyWidget
代理,用于将一个QWidget对象嵌入到QGraphicsScene中
QGraphicsRectltem
可以添加到QGraphicsScene的矩形图元
QGraphicsScene
管理大量2D图元的管理器
QGraphicsSceneContextMenuEvent
图形视图框架中的上下文菜单事件
QGraphicsSceneDragDropEvent
图形视图框架中的拖放事件
QGraphicsSceneEvent
所有图形视图相关事件的基类
QGraphicsSceneHelpEvent
Tooltip请求时的事件
QGraphicsSceneHoverEvent
图形视图框架中的悬停事件
QGraphicsSceneMouseEvent
图形视图框架中的鼠标事件
QGraphicsSceneMoveEvent
图形视图框架中的部件移动事件
QGraphicsSceneResizeEvent
图形视图框架中的部件大小改变事件
QGraphicsSceneWheelEvent
图形视图框架中的鼠标滚轮事件
QGraphicsSimpleTextltem
可以添加到QGraphicsScene的简单文本图元
QGraphicsSvgltem
可以用来呈现SVG文件内容的QGraphicsltem
GraphicsTextltem
可以添加到QGraphicsScene的文本图元,用于显示格式化文本
QGraphicsTransform
创建QGraphicsltems高级矩阵变换的抽象基类
QGraphicsView
显示一个QGraphicsScene内容的部件
QGraphicsWidget
QGraphicsScene中所有部件图元的基类
QStyleOptionGraphicsltem
用于描述绘制一个QGraphicsltem所需的参数

图形视图坐标系统

图形视图基于笛卡尔坐标系;道具在场景中的位置和几何形状由两组数字表示:x坐标和y坐标。当使用未转换视图观察场景时,场景中的一个单元由屏幕上的一个像素表示。
在图形视图中有三种有效的坐标系统:item坐标、scene坐标和view坐标
为了简化实现,Graphics View提供了方便的函数,允许您在三个坐标系统之间进行映射。
渲染时,图形视图的场景坐标对应于QPainter的逻辑坐标,视图坐标与设备坐标相同。在坐标系统文档中,您可以了解逻辑坐标和设备坐标之间的关系。

场景坐标

场景表示所有项目的基本坐标系统。场景坐标系统描述了每个顶级项目的位置,也形成了从视图传递到场景的所有场景事件的基础。场景中的每个项目都有一个场景位置和边界矩形(QGraphicsItem::scenePos(), QGraphicsItem::sceneBoundingRect()),除了它的本地项目pos和边界矩形。场景坐标描述了项目在场景坐标中的位置,它的场景边界矩形构成了QGraphicsScene如何确定场景中哪些区域发生了变化的基础。场景中的变化是通过QGraphicsScene::changed()信号传递的,参数是一个场景矩形列表。

视图坐标

视图坐标是Widget的坐标。视图坐标中的每个单元对应一个像素。这个坐标系的特殊之处在于它相对于小部件或视口,不受所观察场景的影响。QGraphicsView的viewport的左上角总是(0,0),右下角总是(viewport width, viewport height)。所有鼠标事件和拖放事件最初都是作为视图坐标接收的,为了与项目交互,您需要将这些坐标映射到场景。

坐标映射及案例

通常在处理场景中的项目时,将坐标和任意形状从场景映射到项目,从项目映射到项目,或从视图映射到场景是很有用的。
当你在QGraphicsView中点击鼠标时,询问场景光标下的项目是什么
  • 你可以通过调用QGraphicsView::mapToScene()
  • 然后再调用QGraphicsScene::itemAt()
如果你想知道一个项目Item在View中的位置
  • 你可以在项目上调用QGraphicsItem::scenePos()
  • 然后在视图上调用QGraphicsView::mapFromScene()
最后,如果你想要找到视图某区域内的所有项目:
  • 你可以传递一个QPainterPathQGraphicsScene::mapToScene()
  • 然后传递映射路径给QGraphicsScene::items()
你可以通过调用QGraphicsItem::mapToScene()和QGraphicsItem::mapFromScene()将坐标和形状映射到项目的场景或者从场景映射
你也可以通过调用QGraphicsItem:: maptopparent()和QGraphicsItem::mapFromParent()映射到一个项目的父项目,或者通过调用QGraphicsItem::mapToItem()和QGraphicsItem::mapFromItem()映射到项目之间。
所有的映射函数都可以映射点、矩形、多边形和路径。
视图中也有相同的映射函数,用于从场景映射到场景。QGraphicsView::mapFromScene()和QGraphicsView::mapToScene()。要从视图映射到项,首先映射到场景,然后从场景映射到项。
映射函数
描述
QGraphicsView::mapToScene()
从视图坐标系统映射到场景坐标系统
QGraphicsView::mapFromScene()
从场景坐标系统映射到视图坐标系统
QGraphicsItem::mapToScene()
从图形项的坐标系统映射到场景的坐标系统
QGraphicsItem::mapFromScene()
从场景的坐标系统映射到图形项的坐标系统
QGraphicsItem::mapToParent()
从本图形的坐标系统映射到其父图形的坐标系统
QGraphicsItem::mapFromParent()
从父图形项的坐标系统映射到本图形项的坐标系统
QGraphicsItem::mapToItem()
从本图形项的坐标系统映射到另一个图形项的坐标系统
QGraphicsItem::mapFromScene()
从另一个图形项的坐标系统映射到本图形项的坐标系统

其他属性

缩放和旋转

QGraphicsView具有的对视图的操作:
  • scale:缩放
  • rotate:旋转

拖放

因为QGraphicsView间接继承了QWidget,所以它已经提供了与QWidget相同的拖放功能。此外,为了方便起见,图形视图框架为场景和每个项目提供了拖放支持。
当视图接收到拖拽时,它将拖放事件转换为QGraphicsSceneDragDropEvent,然后将其转发到场景。场景接管了这个事件的调度,并将其发送到鼠标光标下接受掉落的第一个项目。
要从一个项目开始拖动,创建一个QDrag对象,将一个指针传递给开始拖动的小部件。项目可以被多个视图同时观察,但只有一个视图可以开始拖动。在大多数情况下,拖动是由于按下或移动鼠标而开始的,因此在mousePressEvent()或mouseMoveEvent()中,您可以从事件中获得原始小部件指针。例如:
为了拦截场景的拖放事件,你在一个QGraphicsItem子类中重新实现QGraphicsScene::dragEnterEvent()和任何你特定场景需要的事件处理程序。您可以在QGraphicsScene的每个事件处理程序的文档中阅读更多关于图形视图中拖放的信息。
项目可以通过调用QGraphicsItem::setAcceptDrops()来启用拖放支持。要处理传入的拖动,重新实现QGraphicsItem::dragEnterEvent(), QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent()和QGraphicsItem::dropEvent()。

 

评论
  • Twikoo
  • Valine