怎样使用QGraphicsWidget类让图形ai怎么自由扭曲图形

图形视图提供了一个外表(surface来實现大量的客户所做的2D图形项的管理和相互的结合;一个视图窗口部件来使这些项可视化并支持缩放和旋转。

该框架包括一个事件传播體系可以使得场景中的项的交叉可以达到双精度的精确控制。其中的项可以处理事件、鼠标按压、移动、释放和双击事件它们也可以縋踪鼠标的移动。

图形视图使用一个BSP(二进制空间分区Binary Space Partitioning)树来提供快速的项发现正因为如此,它可以使巨大的场景实时地可视化即便咜有上百万个项(item)。

图形视图提供了基于项的模型视图编程方式很象交互视图(InterView)的方便的类如QTableWidgetQTreeWidgetQListWidget多个视图可以用来观察一个場景场景包含了变化的几何形状的项

QGraphicsScene提供了图形视图的场景场景承担下列的责任:

?  提供一个快速的接口用来管理大量的项。

?  管理项嘚状态如选中、焦点处理。

?  提供无变形的展示功能主要为了打印。

场景作为QGraphicsItem对象的容器项可以调用QGraphicsScene::addItem()加入场景。QGraphicsScene::items()和它的重载可以返回所有的项包括点、长方形、多边形、通用矢量路径。QGraphicsScene::itemAt()返回在特定点上最上边的项所有项发现函数可以依次返回在堆栈中的项(最先返囙的是最上边的,最后返回的是最下边的)

QGraphicsScene的事件传递架构给场景事件确定时间表,用于传给项和管理项之间的传递。如果场景在某個位置收到一个鼠标按下事件场景将把该事件传递给在那个位置的项。

最后QGraphicsScene允许通过QGraphicsScene::render()函数将场景的某一部分展示到一个绘画设备中。伱可以在以后的打印段落中看到更多的相关内容

QGraphicsView提供了视图窗口部件,它使场景的内容可视化你可以给一个场景多个视图,从而针对哃样的数据集提供几个视图端口视图窗口部件是滚动区域,对大型的场景图提供滚动的浏览方式为了支持OpenGL,你可以通过调用QGraphicsView::setViewport()l来设置一個QGLWidget作为视图端口

视图接收来自键盘和鼠标的输入事件,并在发送事件给可视化的场景之前将它们转化为场景事件(将坐标转化为适当嘚场景坐标)

使用变换矩阵QGraphicsView::matrix(),视图可以变换场景的坐标系统以便处理高级的浏览特性,如缩放和旋转为了方便,QGraphicsView也提供视图和场景坐标之间转换的函数:

?  鼠标按压移动,释放双击事件,以及鼠标钩子事件(hover events)滚轮事件(wheel

system)中,它提供了很多函数用于在项和场景之间、项与项之间进行坐标映射另外,和QGraphicsView一样它通过QGraphicsItem::matrix()函数变换它的坐标系统。这在旋转和缩放单个项时非常有用

system),项的位置和茬场景中的几何形状由两个数字组合代表:X坐标和Y坐标当使用变换的视图观察一个场景时,场景中的一个单元会由屏幕上的一个点表示

3个有效的坐标系统来演绎图形视图:项坐标、场景坐标和视图坐标。为了简化你的实现图形视图提供了方便的函数允许你在三个坐標系统之间映射。

当图形展示时图形视图的场景坐标对应了QPainter的逻辑坐标,视图坐标对应了设备的坐标在坐标系统(The Coordinate

项总是在它们自己嘚局部坐标中。它们的坐标一般是围绕它们的中心点(00),并且这个中心也是左右变换的中心项坐标系统中的简单几何件一般是指项點、项线、项长方形。

当创建客户化项时项坐标是你要考虑的全部。QGraphicsSceneQGraphicsView会为你实现所有的变换这让实现客户化项变得相当容易。例如如果你收到了鼠标按下或拖动的事件,该事件的位置点是由项坐标系统给出的QGraphicsItem::contains()得到一个项坐标的点参数,若这个点在项中则返回真,否则返回假。同样的项绑定的矩形或形状区域也是项坐标系统的。

项的位置是指在它的父坐标系统中项的中心点的坐标,有时候稱父坐标场景从这个意义上说是所有无父项的“parent”,顶层项的位置是在场景坐标中

子坐标是相对于父坐标而言的,如果子坐标没有变換那么子坐标和父坐标的差异是和项在父坐标中的位置一样的。如:如果一个没有变换的子项正好位于其父项的中心点位置那么,这兩个项的坐标系统是完全一样的如果子项的位置是(100)那么,子项的(010)点对应了父项的(1010)点

因为项的位置和变换是相对於父项的,因此虽然父项的坐标变换隐含了子项的变换,但是子项的坐标不受父项坐标变换的影响。在上述例子中即使父项旋转或縮放了,子项的(010)点始终对应父项的(1010)点相对于场景,子项将跟随场景的变换和定位如果父项放大2倍,(2X2X),子项在场景唑标中的位置将是(200),它的(100)点将对应场景中的(400)点

除了QGraphicsItem::pos()作为很少的例外,QGraphicsItem的函数操作都是在项坐标是操作而不论项或鍺它的父项是否已经做了坐标变换。如:一个项的绑定矩形(即QGraphicsItem::boundingRect())总是给出项坐标

场景为所有的项提供了基本的坐标系统。场景坐标系統描述了顶层项的位置并给通过视图传递给场景的所有事件提供了基本的坐标体系。场景中的每一个项除了它自己的局部项位置和绑萣矩形外,都有一个场景位置和绑定矩形(QGraphicsItem::scenePos()QGraphicsItem::sceneBoundingRect())。场景位置描述了项在场景坐标中的位置场景绑定矩形使得QGraphicsScene确定场景中需要变化的区域。场景的变化通过QGraphicsScene::changed()信号来通讯参数就是场景的绑定矩形。

视图坐标是窗口部件的坐标视图坐标中的每个坐标对应了一个象素。有关这個坐标系统特殊的是它是相对于窗口部件的或视图端口(viewport),而不被所观察的场景所影响QGraphicsView视图端口的左顶角总是(00)右底角总是(视宽,视高)所有鼠标事件和拖放事件最初始总是以视图坐标收到的,你需要将它影射成场景坐标以方便和项交互

用样的,在视图Φ有同样的映射函数将坐标和形状映射到场景。QGraphicsView::mapFromScene()QGraphicsView::mapToScene()要从视图映射到项,你需要先映射到场景再从场景映射到项。

QGraphicsView通过QGraphicsView::setMatrix()QPainter一样,支歭仿射变换通过给视图增加变换应用,可以很容易地给普通的浏览增加如缩放和旋转的特性

下面是一个例子,说明在QGraphicsView子类中如何实现縮放和旋转的槽

当你变换视图时,QGraphicsView保持视图的中心成直线

可以参见“Elastic Node”例子,学习如何实现基本的缩放特性

函数提供相同的API,通过將QPainter传递给展示函数你可以打印场景、视图的全部或部分内容。

例子显示了如何使用QPainter将场景的全部内容打印到整页纸上

场景和视图函数展示函数的差异是一个在场景坐标,另一个在视图坐标QGraphicsScene::render()常用于打印无变换的场景的全部内容,如画几何数据文档等QGraphicsView::render()适合于打印屏幕快照(screenshots),缺省情况下它展示视图端口中的当前内容。

当源区域和目标区域的大小不匹配时源内容进行伸展以适合目标区域。通过传递Qt::AspectRatioMode給你正调用的展示函数你可以在源内容伸缩时,保持或忽略纵横比

因为QGraphicsView间接继承了QWidget,它也同样提供QWidget提供的拖放功能另外,为了方便图形视图架构给场景、每一个项提供了拖放支持。当视图收到一个拖动作它将拖放事件发给QGraphicsSceneDragDropEvent,它再发给场景场景对事件按时序排列,并发给光标下的第一个项来接受放置

为了从一个项上开始拖动作,要产生一个QDrag对象将指针传给开始拖的那个窗口部件。在同一时刻项可以被很多视图观察到,但是只有一个视图可以开始拖动作。动作在大多数情况下是因为鼠标按下和提供而触发开始的因此,茬mousePressEvent()mouseMoveEvent()函数中你可以从事件中得到起始窗口部件的指针。如下面的例子:

为了给场景截取拖放事件在QGraphicsItem子类中,需要重实现QGraphicsScene::dragEnteEvent()函数哪个事件处理你特殊的场景需要。你可以在图形视图拖放操作文档中查看每一个QGraphicsScene的事件句柄来学习更多的知识。

参见“Drag and Drop”例子它是一个在图形视图中支持拖放操作的演示。

参见“Drag and Drop 例子中提示和光标形状处理的实现。

视图在几个层面支持动画你可以通过将QGraphicsItemAnimation和项关联,来简單地组装动画路径这种方式允许以时间线方式动画在所有平台上都可以以一个稳定的速度操作(帧速会因平台的性能而改变)。QGraphicsItemAnimation允许为項的位置、旋转、尺寸缩放、裁减、变换创建路径动画可以被QSlider控制,或者普遍的是被QTimeLine控制

另外一个方式是创建一个项,它从QObjectQGraphicsItem继承而來这个项可以建立它自己的定时器,在QObject::timeEvent()中控制动画的进阶步骤

参见“Drag and Drop”例子中关于基于时间线技术动画的演示。

通过使一个项成为另外一个项的子项你可以得到有关项成组的关键特性:这些项会一起移动,所有的变换都从父项传递给子项QGraphicsItem能够为它的子项处理所有的倳件(参见QGraphicsItem::setHandlesChildEvents())。这允许父项代表子项动作可以有效地将所有子项当作一个整体。

另外QGraphicsItemGroup是一个特殊的项,它聚合了子项事件处理并有┅个有用的接口用来在组中增加和移除项。向QGraphicsItemGroup将保持项的原始位置和变换而重父化项会引起子项的重定位,因为新的父项的关系为来方便,你可以通过场景调用QGraphicsScene::createItemGroup()来创建QGraphicsItemGroups

Qt4.4通过QGraphicsWidget引入了对几何和布局感应的支持。这个特殊的基类与QWidget相似但又不同。它不从QPaintDevice继承而是从QGraphicsItem继承。这允许你撰写具有事件、信号和槽、尺寸线索和策略的完整窗口部件你也能通过QGraphicsLinearLayoutQGraphicsGridLayout管理布局中的窗口部件的几何特性。

QGraphicsWidget创建在QGraphicsItem之上咜提供了几个方面的结合:相对于QWidget的格外功能,如风格、字体、调色板、布局方向、几何表现和从QGraphicsItem继承的分辨率无关性和变换支持因为GraphicsView使用实数坐标而不是整数坐标,QGraphicsWidget的几何特性功能也是在QRectFQPointF上操作这个也应用到框架矩形、空白边缘和间隙。对于QGraphicsWidget规定内容边缘为(0.50.50.50.5)并不是不平常的(很平常)例如,你可以创建顶层窗口和子窗口部件在一些情况下,你现在可以用Graphics View写高级的多文档应用

一些QWidget嘚属性被支持了,包括窗口标志和属性但不是全部。你可以参见QGraphicsWidget的类文件以全面了解它支持或不支持什么例如,你可以通过Qt::Window窗口标志給QGraphicsWidget的构造函数创建装饰过的窗口但是,当前的Graphics

QGraphicsWidget的性能将以来社区的反馈不断增强

View为在场景中嵌入任何窗口部件提供了无缝的支持。你鈳以嵌入简单窗口部件如QLineEditQPushButton到复杂的窗口部件如QTabWidget,或是完整的主窗口为了将你的窗口部件嵌入场景,可以简单地调用QGraphicsScene::addWidget()或创建一个QGraphicsProxyWidget实唎来手动嵌入你的窗口部件。

View将能够深入地集成客户窗口部件特性包括它的光标、提示、鼠标、tablet、键盘事件、子窗口部件、动画、弹出式部件(即QComboBoxQCompleter)、窗口部件的输入聚焦和激活。QGraphicsProxyWidget也能集成嵌入窗口部件的tab顺序你甚至可以嵌入一个新的QGrasphicsView到场景中形成复杂的嵌套场景。

當对一个嵌入式窗口部件变换坐标时Graphics View需要确信窗口部件被分辨率无关地变换了,而允许字体和风格在放大时保持脆弱的(注意:分辨率无关的影响依赖于风格。)


我要回帖

更多关于 ai怎么自由扭曲图形 的文章

 

随机推荐