QGraphicsScene【详细描述】

QGraphicsScene提供绘图场景,场景是不可见的,它作为抽像的管理图形项 QGraphicsItems的容器,用户可以向场景添加图形项,获取场景中的图形项等。它与图形视图QGraphicsView一起用于可视化2D图形项目,如线、矩形、文本,甚至是自定义图形元素。


场景

QGraphicsScene是图形视图框架的一部分。

  • 它提供管理大量图形项的快速接口。
  • 它将事件传播给每个图形项。
  • 它管理每个图形项的状态,如:选择、焦点状态等。
  • 它管理未经变换的渲染功能,主要用于打印。

QGraphicsScene还提供了一些功能,让用户确定图形项的位置,并确定图形项在场景的可见性。使用QGraphicsView,可以可视化整个场景,也可以放大并仅查看场景的一部分。

QGraphicsScene scene;
scene.addText("Hello, world!");

QGraphicsView view(&scene);
view.show();

视图 

如上代码,QGraphicsScene并不可见,它只是管理图形项,所以,用户需要创建一个QGraphicsView 控件来显示场景内容。可以为一个场景设置多个视图,用于对同一个数据集提供不同的视口。

如上图,视图1比场景更大,它显示场景的全部内容。缺省情况下,当视图大于场景,场景在视图的中间部分显示,可以设置视图的Alignment属性控制场景在视图中的显示位置。视图2小于场景,它只能显示场景的一部分,并提供滚动条在场景内移动。


图形项

 图形项是基本的图形元件,其基类是QGraphicsItem,QT提供了常见图形项的绘制函数。图形项支持以鼠标、键盘、拖放以及组合操作。组合可以是父子项关系,也可以通过QGraphiceItemGroup类进行。用户可以通过编写槽函数代码,实现各种编辑功能,图形项支持父子关系,还支持碰撞检测。

小结:

视图、场景和图形项的关系如上图,场景是图形项的容器,可以在场景上绘制很多图形项,每个图形项都是一个对象,有相关事件和动作。

视图是显示场景一部分区域的视口,场景可以有多个视图。


坐标系统

QGraphicsView有三个坐标系:图形项坐标、场景坐标、视图坐标。

  • 场景坐标等价于QPainter的逻辑坐标,一般以场景的中心为原点,它是所有图形项的基础坐标,描述了每个顶层图形项的位置,创建场景时可以定义场景矩形的坐标范围。例:
scene=new QGraphicsScene(-400,-300,800,600);
//场景左上角-400,-300,宽800,高600
  • 视图坐标与设备坐标(例如显示器)相同,这是物理坐标,默认以左上角为原点,单位是像素,它只与widget视口有关,与观察的场景无关。QGraphicsView视口的左上角总是(0,0)。
  • 图形项坐标是局部逻辑坐标,以图件中心为原点,以中心为(0,0),这也是各种变换的中心。绘制图形项时只需要考虑其局部坐标,场景和视图坐标会自动进行转换。

坐标映射

场景到图形项、图形项到图形项,视图到场景之前的坐标变换称之为坐标映射。

例如:在QGraphicsView视口上单击鼠标,通过函数QGraphicsView::mapToScene()可将视口坐标映射为场景坐标,然后用QGraphicsScene::itemAt()函数获取场景中鼠标光标处的图形项。


一般步骤

要将图形项添加到场景,首先构造QGraphicsScene对象。然后有两种操作:
 

一是通过调用QGraphicsItem添加你的图形项addItem()。

二是调用加入椭圆 addEllipse(),加入线 addLine(), 加入路径addPath(), 加入像素图形addPixmap(), 加入多边形addPolygon(), 加入矩形addRect(), 加入文本addText()等函数。这些函数都返回一个指向新添加的图形元素的指针。
 

添加的图形元素尺寸相对于当前坐标系,图形位置在场景中初始化为(0,0)。

然后,使用图形视图 QGraphicsView就可以可视化场景了。

当场景更改时(比如当项目移动或变形时),QGraphicsScene 发出changed() 信号。若要删除一个图形元素,调用 removeItem().。

q图形场景使用一种索引算法来有效地管理项目的位置。默认情况下,使用BSP(二进制空间分区)树;一种适用于大多数项目保持静态的大型场景的算法。,不要四处移动)。您可以通过调用设置项索引方法()来选择禁用此索引。有关可用的索引算法的更多信息,请参阅项索引方法属性。

QGraphicsScene使用索引算法有效管理图形元素的位置。默认情况下,使用 BSP(二进制空间分区)树,这是一种适用于大量元素保持静止(即不四处移动)的大型场景的算法。您可以通过调用 setItemIndexMethod()来选择禁用此索引。有关索引算法的详细信息参阅 itemIndexMethod 属性。


场景的边界矩形通过调用 setSceneRect()来设置的。图形元素可以放置在场景的任何位置,场景的大小默认是无限的。

场景矩形仅用于内部簿记,以维护场景的内图形的索引。如果未设置场景矩形,QGraphicsScene将使用所有图形元素组合的边界区域, itemsBoundingRect()返回场景矩形。但是, itemsBoundingRect() 是一个相对耗时的功能,因为它需要收集场景中每个图形的位置信息来计算。因此,在大型场景上操作时,还是用 setSceneRect()设置一下吧。


QGraphicsScene最大的优势之一是它能够有效地确定图形的位置。即使场景中有数百万个图形,titems() 函数也可以在几毫秒内确定项目的位置。items() 有多个重载,例如在某个位置查找,在多边形或矩形内部查找,在多边形或矩形相交的区域查找等,它返回的项目列表按图形堆叠顺序排序,最上面的项目是列表中的第一个图形元素。为方便起见,还有一个 itemAt() 函数,用于返回给定位置的最顶层图形。

QGraphicsScene 始终维护场景的选择信息。选择图形调用 setSelectionArea(),要清除当前选择调用clearSelection(),调用 selectedItems() 可以获取所有选定项的列表。


 事件处理和传播 

QGraphicsScene的另一个职责是传播来自 QGraphicsView的事件。要将事件发送到场景,需要构造一个继承 QEvent 的事件,然后使用 QCoreApplication::sendEvent() 等方式发送该事件。

 event()  负责将事件发送到各个图形元素。常见的按键事件由keyPressEvent() 处理,鼠标按下事件由 mousePressEvent() 处理。

关键事件将传递到焦点图形。设置焦点项可以调用setFocusItem(),传递接受焦点的项,也可以调用图形元素本身的QGraphicsItem::setFocus().。调用focusItem()  可以获取当前焦点项目。

为了与控件兼容,场景还保留了自己的焦点信息。默认情况下,场景没有焦点,并且所有关键事件都将被丢弃。如果调用了 setFocus() ,或者场景中的某图形获得了焦点,则场景会自动获得焦点。如果场景有焦点, hasFocus() 将返回 true,并且关键事件将转发到焦点图形(如果有)。如果场景失去焦点(或调用了 clearFocus()),场景会保持其图形的焦点信息,一旦场景重新获得焦点,它将确保之前最后一个焦点元素重新获得焦点。

对于鼠标悬停效果,QGraphicsScene会调度悬停事件。如果图形元素接受悬停事件(参见 QGraphicsItem::acceptHoverEvents()),则当鼠标进入其区域时,它将收到一个事件。当鼠标继续在图形区域内移动时,QGraphicsScene将向其发送GraphicsSceneHoverMove 事件。当鼠标离开图形区域时,图形将收到一个GraphicsSceneHoverLeave 事件。

所有鼠标事件都传递到当前“鼠标抓取器”项,如果图形可以接受鼠标事件(参见QGraphicsItem::acceptedMouseButtons()))并接收鼠标按下,则该项目将成为场景的鼠标抓取器。它保持鼠标抓取器,直到在未按下其他鼠标按钮时收到鼠标释放。您可以调用mouseGrabberItem()  来确定当前正在抓取鼠标的项目。


<<< 返回上一级 【QGraphicsScene类】

<<< 返回根页面

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值