【翻译 + 整理】Qt图形视图框架概述

一、描述

1、图形视图框架提供了一个用于管理大量定制的二维图形项目并与之交互的界面,以及一个用于可视化项目的视图,并支持缩放和旋转。

2、图形视图框架包括一个事件传播体系结构,允许对场景中的项目提供精确的双精度交互功能。项目可以处理按键事件、鼠标按下、移动、释放和双击事件,还可以跟踪鼠标移动。

3、图形视图框架使用BSP树来提供非常快速的图形项查找,因此,它可以实时地可视化大型场景,即使有数百万个项目。

二、图形视图框架体系结构

2.1、场景

QGraphicsScene提供了“图形视图”场景。场景用作QGraphicsItem对象的容器。场景具有以下职责:

  • 提供用于管理大量项目的快速(指处理速度)界面。
  • 将事件传播到每个项目,场景的事件传播架构可安排场景事件以交付给项目,并管理项目之间的传播。如果场景在某个位置收到鼠标按下事件,则场景会将事件传递到该位置上的任何项目。
  • 管理项目状态,例如选择和焦点处理。
  • 提供渲染功能(QGraphicsScene::render()函数将场景的一部分渲染到绘制设备中)。

 2.2、视图

1、QGraphicsView提供了视图小部件,该部件可将场景的内容可视化。可以将多个视图附加到同一场景,以在同一数据集中提供多个视口。视图小部件是一个滚动区域,并提供用于在大型场景中导航的滚动条。

2、视图从键盘和鼠标接收输入事件,并将其转换为场景事件(在适当的情况下,将事件发送到场景坐标之前将其转换为场景坐标)。

2.3、图形项

1、QGraphicsItem是场景中图形项的基类。图形视图框架为典型形状提供了几个标准项,但是在编写自定义图像项时,可以继承QGraphicsItem自定义图形项。除其他外,QGraphicsItem支持以下功能:

  • 鼠标按下、移动、释放、双击、悬停、滚轮和上下文菜单事件。
  • 键盘输入焦点和按键事件。
  • 拖放。
  • 通过父子关系以及QGraphicsItemGroup进行分组。
  • 碰撞检测。

2、图形项位于局部坐标系中。它还提供了许多用于在图形项与场景之间以及图形项与图形项之间映射坐标的功能。

3、图形项可以使用矩阵transform()变换其坐标系。这对于旋转和缩放单个项目很有用。

4、图形项可以包含其他项(子项)。父项的转换由其所有子项继承。

5、图形项通过shape()函数和collidesWith()函数支持冲突检测,这两个函数都是虚拟函数。通过从shape()返回项目的形状作为局部坐标QPainterPath,如果要提供自己的冲突检测,可以重新实现collidesWith()。

三、图形视图框架类列表

四、图形视图框架坐标系统

图形视图框架坐标系统基于笛卡尔坐标系。图形项在场景中的位置和几何形状由两个数字表示:x坐标和y坐标。当使用未变换的视图观察场景时,场景中的一个单元由屏幕上的一个像素表示。

图形视图框架中有三个有效的坐标系统在起作用:图形项坐标,场景坐标和视图坐标。为了简化实现,图形视图框架提供了方便的功能,可以在三个坐标系之间进行映射。

渲染时,场景坐标对应于QPainter的逻辑坐标。绘图坐标系统

4.1、图形项坐标

1、图形项位于其自己的本地坐标系中。坐标原点(0,0)为在左上角。坐标原点也是变换的中心点。

2、创建自定义图形项时,只需要关注图形项坐标,场景和视图将为您执行所有转换。

3、图形项的坐标原点在父项中的点称为父坐标。对于无父项的图形项,其父坐标就是在场景中的坐标。

4、因为子项的位置和变换是相对于父项的,所以子项的坐标不受父项变换的影响,尽管父项的变换会隐式地变换子项。

如图,3是2的子项,尽管旋转2的时候3也会跟着旋转,但3的坐标始终相对于2是不变的。

4.2、场景坐标

场景代表所有图形项的基本坐标系。场景坐标系描述了每个顶级图形项的位置,并且还构成了从视图传递到场景的所有场景事件的基础。场景中的每个图形项除了其本地位置QGraphicsItem::pos()和边界矩形QGraphicsItem::boundingRect()之外,还具有场景位置和场景边界矩形(QGraphicsItem::scenePos(),QGraphicsItem::sceneBoundingRect())。场景位置描述了t图形项在场景坐标中的位置,其场景边界矩形构成了场景如何确定场景的哪些区域已更改的基础。

4.3、视图坐标

视图坐标是小部件的坐标。视图坐标中的每个单位对应一个像素。该坐标系的特殊之处在于它是相对于小部件或视口的,并且不受所观察场景的影响。 视图的视口的左上角始终为(0,0),而其右下角始终为(视口宽度,视口高度)。所有鼠标事件和拖放事件最初都是作为视图坐标接收的。

五、图形视图框架的特点

5.1、缩放和旋转

视图提供了便利的函数进行缩放和旋转。

5.2、打印

可通过其渲染功能QGraphicsScene::render()和QGraphicsView::render()提供单行打印。这些函数提供相同的API:通过将QPainter传递给任一渲染函数,可以使场景或视图将其全部或部分内容渲染到任何绘画设备中。例:

 QGraphicsScene scene;
 QPrinter printer;
 scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));

 if (QPrintDialog(&printer).exec() == QDialog::Accepted) 
 {
     QPainter painter(&printer);
     painter.setRenderHint(QPainter::Antialiasing);
     scene.render(&painter);
 }

场景和视图渲染功能之间的区别在于,一个在场景坐标中操作,另一个在视图坐标中操作。QGraphicsScene::render()通常是打印未变换场景的整个片段的首选。 另一方面,QGraphicsView::render()适合拍摄屏幕截图。

 QGraphicsScene scene;
 scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));

 QImage image(scene->sceneRect().toRect().size(),QImage::Format_RGB32);
 QPainter painter(&image);
 painter.setRenderHint(QPainter::Antialiasing,true);
 painter.fillRect(image.rect(),Qt::white);
 scene->render(&painter);

 image.save("scene.png");

5.3、拖放

由于QGraphicsView间接继承了QWidget,因此它已经提供了与QWidget提供的拖放功能相同的功能。另外,为方便起见,图形视图框架为场景以及每个图形项提供了拖放支持。当视图接收到拖动时,它将拖放事件转换为QGraphicsSceneDragDropEvent,然后将其转发到场景。场景将接管此事件,并将其发送到接受放置的鼠标光标下的第一个图形项。

要从项目开始拖动,请创建QDrag对象,并将指针传递到开始拖动的小部件。 可以同时通过多个视图观察项目,但是只有一个视图可以开始拖动。Qt拖放

5.4、光标和工具提示

与QWidget一样,QGraphicsItem也支持光标(QGraphicsItem::setCursor())和工具提示(QGraphicsItem::setToolTip())。当鼠标光标进入图形项区域时,QGraphicsView会激活光标和工具提示。

5.5、动画

1、图形视图框架支持多个级别的动画。 可以使用动画框架轻松地组装动画。 为此,需要从QGraphicsObject继承项并将QPropertyAnimation与它们关联。 QPropertyAnimation允许设置任何QObject属性的动画。

2、另一种方式是创建一个继承自QObject和QGraphicsItem的自定义项目。该项目可以设置自己的计时器,并通过QObject::timerEvent()中的增量步骤控制动画。

3、第三种方式是通过调用QGraphicsScene::advance()来推进场景的,QGraphicsScene::advance()依次调用QGraphicsItem::advance()。

5.6、启用OpenGL渲染

 QGraphicsView view(&scene);
 QOpenGLWidget *gl = new QOpenGLWidget();
 QSurfaceFormat format;
 format.setSamples(4);
 gl->setFormat(format);
 view.setViewport(gl);

5.7、图形项分组

通过使一个图形项成为另一个图形项的子项,可以实现图形项分组的最基本特征:这些图形项将一起移动,并且所有转换都从父项传播到子项。
QGraphicsItemGroup是一个特殊项,它将子事件处理与界面相结合,用于在组中添加项或从组中删除项。 将图形项添加到QGraphicsItemGroup中将保留该项目的原始位置和变换,而通常重新父项会导致子级相对于其新父级重新定位自身。

5.8、小部件和布局

QGraphicsWidget引入了对几何和布局感知项的支持。这个特殊的基础图形项类似于QWidget,但是与QWidget不同,它不是从QPaintDevice继承而来的而是继承自QGraphicsObjectQGraphicsLayoutItem。这使您可以编写带有事件,信号槽,大小提示和策略的完整窗口小部件,还可以通过QGraphicsLinearLayoutQGraphicsGridLayout管理布局中的窗口小部件几何形状。

5.9、嵌入式小部件支持

图形视图框架提供将任何小部件嵌入到场景中的无缝支持。要将小部件嵌入场景,只需调用QGraphicsScene::addWidget(),或创建QGraphicsProxyWidget的实例即可手动嵌入小部件。图形视图框架确保对窗口小部件进行独立的分辨率转换,从而在放大时使字体和样式保持清晰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值