Graphics View以笛卡尔坐标系为基础,items在scene上的位置和几何结构由x坐标和y坐标表示。当我们用未转置的view来观察scene时,scene中的一个单元由屏幕中的一个像素表示。
注:由于Graphics Views使用Qt的坐标系,y轴反向(y轴正方向向上)的坐标系是不支持的。
Graphics View中有三个实用的坐标系:item坐标系、scene坐标系和view坐标系。
为了简化坐标系相关代码,Graphics View提供了便捷的函数,以方便在三个坐标系间转换。
转换坐标时,scene坐标系相当于QPainter的逻辑坐标系,view坐标系相当于设备(device)坐标系,你可以在索引里搜索:Coordinate System,阅读有关两坐标系之间的关系。
Item坐标系
Item拥有它们自己的逻辑坐标系。坐标系的原点(0,0)通常在它的中心。它同时也是坐标转换的中心。item坐标系中的基本几何图形:item点、item线、和item矩形(存在一个item中画了几个子item的情况)。
当你创建自己的item时,item坐标系是重点; QGraphicsScene and QGraphicsView会提供其他两个坐标系的坐标转换功能。这样以来,实现自己的item就很简单了,例如,如果你收到一个mouse press或drag enter事
件,event的位置是在item坐标系中给出的。当一个点在你的item里时,虚函数QGraphicsItem::contains()返回ture,函数的参数是item坐标系中的一个点。同样,item的 bounding rect 和 shape函数返回值也是在item坐标系中。
item的位置指:item的中心点在父坐标系(parent‘s coordinate system)中的位置;sometimes referred to as parent coordinates。scene相当于所有没有父组件的item的parent。顶级items的位置在scene坐标系中。
子坐标系是相对于父坐标系而言的。若子组件没有transformed,父、子坐标系间的差距就如item和父组件的差距一样。例如,如果一个untransformed的子组件精确位于其父组件的中心点,那么这两个item的坐标系是完全相同的。如果子组件的坐标是(10,0),那么在子坐标系中的(0,10)点,就是父坐标系中的(10,10)点。
因为组件的位置和transformation都与其父组件有关,但父组件的transformation不会影响到子组件的坐标系,虽然父组件暗中transforms了子组件。在以上的例子中,即使父组件旋转或是缩放,子组件的(0,10)点依然与父组件的(10,10)点重合。然而,相对于scene,子组件会跟随父组件的transformation和位置。如果父组件放大2倍,那么子组件的位置会在scene的(20,0)点,它的(10,0)点会在scene的(40,0)点。
忽略item或它的父组件的transformation,QGraphicsItem‘s的函数在item坐标系中进行操作, QGraphicsItem::pos()函数是少数几个例外 。例如,QGraphicsItem::boundingRect()函数返回的是item坐标系中的坐标。
scene坐标系
scene代表了所有items的基础坐标系统,scene坐标系描述了所有顶级item的位置,同时也是所有从view传到scene中的event的基础。scene中的每个item,除了item坐标系中的位置和边界,还有它的scene位置和边界(QGraphicsItem::scenePos(), QGraphicsItem::sceneBoundingRect())。其中item的scene边界区域,也是scene确定哪些区域发生了改变的关键。scene发生改变时,发出信号: QGraphicsScene::changed() ,其参数就是一个scene中rectangles的列表。
view坐标系
view坐标系是widget的坐标系。view坐标系中的每个单元都是一个像素。其特点是:与widget或视口(viewport)相关,且不被所观察的scene影响。view的左上角坐标是(0,0),右下角坐标是(viewport width,viewport height)。所有鼠标事件和drag、drop事件的最原始的接收者是view坐标系,为了与items进行交互,你需要将这些坐标映射到scene坐标系。
坐标映射
当处理scene中的items时,经常需要将坐标和任意形状映射从scene坐标系到item坐标系,有时从一个item坐标系映射到另一个item坐标系,或是从view坐标系映射到scene坐标系。
例如,当你在viewport中点击鼠标时,你可以问scene鼠标下点击的是哪个item( QGraphicsView::mapToScene()-》QGraphicsScene::itemAt())
如果你想知道scene中的item位于viewport的什么位置,可以先调用
item的 QGraphicsItem::mapToScene() ,然后调用view的mapFromScene()。你如果还想知道view中一个椭圆里有哪些items,
将QPainterPath作为参数传给mapToScene()。然后将映射后的path作为参数传递给 QGraphicsScene::items()。
你可以将坐标和形状映射到scene或从scene映射回来,通过函数:QGraphicsItem::mapToScene() and QGraphicsItem::mapFromScene()。你也可以映射到父组件或映射回来,通过函数: QGraphicsItem::mapToParent() 和QGraphicsItem::mapFromParent()。或者在item之间进行映射,通过函数: QGraphicsItem::mapToItem() and QGraphicsItem::mapFromItem()。所有的映射函数都能处理点、矩形、多边形和pahts。
在view中也存在着同样的函数来完成与scene之间的映射。QGraphicsView::mapFromScene() and QGraphicsView::mapToScene(),从view映射到item,需要scene作为中转。
Key Features
zooming and rotating
Pringting
Drag and Drop
CUrsors and Tooltips
Animation
OpenGL Rendering
Item Groups
Widgets and Layouts
Embedded Widget Supporting