赞
踩
图形视图基于笛卡尔坐标系;项目在场景中的位置和几何图形由两组数字表示:X 坐标和 Y 坐标。使用未变换的视图观察场景时,场景上的一个单元由屏幕上的一个像素表示。
图形视图中有三种有效的坐标系:
- 项目坐标
- 场景坐标
- 视图坐标
为了简化实现图形视图提供了三个坐标系之间进行映射。
项目位于其自己的局部坐标系中。它们的坐标通常以中心点 (0, 0) 为中心,这也是所有变换的中心。项目坐标系中的几何基元通常称为项目点、项目线或项目矩形。
创建自定义项目时,您只需担心项目坐标;QGraphicsScene 和 QGraphicsView 将为您执行所有转换。这使得实现自定义项变得非常容易。
项目位置是项目在其父坐标系中的中心点的坐标;有时称为父坐标。从这个意义上说,这个场景被视为所有无父母项目的“父母”。顶级物品的位置位于场景坐标中。
子坐标相对于父坐标。如果子坐标未变换,则子坐标和父坐标之间的差异与父坐标中项目之间的距离相同。例如:如果未转换的子项精确定位在其父项的中心点,则这两个项的坐标系将相同。但是,如果子项的位置是 (10, 0),则子项的 (0, 10) 点将对应于其父项的 (10, 10) 点。
由于项的位置和转换相对于父项,因此子项的坐标不受父项转换的影响,尽管父项的转换隐式变换了子项。在上面的示例中,即使父级旋转和缩放,子项的 (0, 10) 点仍将对应于父项的 (10, 10) 点。然而,相对于场景,孩子将跟随父母的转变和位置。如果父项缩放 (2x, 2x),则子项的位置将位于场景坐标 (20, 0),其 (10, 0) 点将与场景中的点 (40, 0) 相对应。
场景表示其所有项目的基本坐标系。场景坐标系描述每个顶级项目的位置,也构成了从视图传递到场景的所有场景事件的基础。
- 项目可以使用 scenePos()来查看在场景的位置
- 项目使用sceneBoundingPect()来查看场景的边界矩形
- 场景中的变化使用QGraphicsScene::changed()信号进行通信
视图的坐标是部件的坐标,视图坐标的每一个单位对应一个像素,原点为(0,0)总是在QGraphicsView视口的左上角,所有的鼠标事件和拖放事件最初都是使用视图视图坐标接收。
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(-200,-200,400,400);//创建一个场景
- QGraphicsRectItem item1(0,0,100,100);//创建一个圆
- item1.setPos(0,0);//设置位置
- scene.addItem(&item1);
- QGraphicsView view2;//创建第一个视图
- view2.setScene(&scene);//设置场景
- view2.resize(400,400);
- view2.show();//显示
- return a.exec();
- }
QGraphicsScene scene(-200,-200,400,400);//创建一个场景
这段代码代表的是该场景是从(-200,-200)到(400,400)的一个矩形
- QGraphicsView view2;//创建第一个视图
- view2.setScene(&scene);//设置场景
- view2.resize(400,400);//重置视图大小
- view2.show();//显示
- 如果没设置位置的话,项目的(0.0)点会放置在场景的(0,0)点
- 可以使用setPos()修改项目在视图中的位置
例一:场景为QRectF(0,0,400,400),项目为(0,0,100,100)
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
- scene.addItem(&item1);
- //视图部分省略
由于项目的起始点为(0,0 ),默认放到场景的位置为(0,0)
例二:场景为QRectF(-200,-200,400,400),项目为(0,0,100,100)
- QGraphicsScene scene(-200,-200,400,400);//创建一个场景
- QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
- scene.addItem(&item1);
使用setPos()修改位置
- QGraphicsScene scene(-200,-200,400,400);//创建一个场景
- QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
- scene.addItem(&item1);
- item1.setPos(-200,-200);//把位置设置为-200,-200
例一:场景为QRectF(0,0,400,400),项目为(-50,-50,100,100)
将项目中的(0,0)点放到场景中的(0,0)点,由于项目的起始坐标为(-50,-50)宽高为(100,100),所以(0,0)点为项目的中心点
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsRectItem item1(-50,-50,100,100);//创建一个矩形
- scene.addItem(&item1);
使用setPos()设置位置
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsRectItem item1(-50,-50,100,100);//创建一个矩形
- scene.addItem(&item1);
- item1.setPos(50,50);//把位置设置为50,50
在处理场景中的项时,将坐标和任意形状从场景映射到项、从项映射到项或从视图映射到场景非常有用。
当你在QGraphicsView中点击鼠标时,可以通过QGraphicsView::mapToScene(),以及QGraphicsScene::itemAt()来获取光标下的图型项,获取在视图的一个椭圆形中包含的图形项,先传递一个QPainterPath参数给mapToScence()函数,然后传递映射后的路径给QGraphicsScene::items()函数。
QGraphicsView::mapToScence() | 从视图坐标系统映射到场景坐标系统 |
QGraphicsView::mapFromScene() | 从场景坐标系统映射到视图坐标系统 |
QGraphicsItem::mapToScene() | 从图形项的坐标系统映射到场景坐标系统 |
QGraphicsItem::mapToParent() | 从本图形项的坐标系统映射到其父图形项的坐标系统 |
QGraphicsItem::mapFromParent() | 从父图形项的坐标系统映射到本图形项的坐标系统 |
QGraphicsItem::mapToItem() | 从本图形项的坐标系统映射到另一个图形项坐标系统 |
QGraphicsItem::mapFromItem() | 从另一个图形项的坐标系统到本场景坐标系统 |
创建一个C++文件,继承自QGraphicsView,并重写鼠标点击事件
- #ifndef MYVIEW_H
- #define MYVIEW_H
- #include<QGraphicsItem>
- #include<QGraphicsView>
- #include<QGraphicsScene>
- #include<QMouseEvent>
- #include<QDebug>
-
- class MyView:public QGraphicsView
- {
- public:
- MyView();
- void mousePressEvent(QMouseEvent *event);//鼠标点击事件
- };
-
- #endif // MYVIEW_H
-
-
-
-
- #include "myview.h"
-
- MyView::MyView()
- {
-
- }
-
- void MyView::mousePressEvent(QMouseEvent *event)//鼠标点击事件
- {
- QPoint viewPos=event->pos();//获取鼠标在视图中的位置
- qDebug()<<"viewPos:"<<viewPos;
- QPointF scenePos=mapToScene(viewPos);//用视图位置获取在场景的位置
- qDebug()<<"scenePos:"<<scenePos;
- QGraphicsItem *item=scene()->itemAt(scenePos,QTransform());//获取该位置的项目
- if(item)
- {
- QPointF itemPos=item->mapFromScene(scenePos);//获取项目在场景中的位置
- qDebug()<<"itemPos:"<<itemPos;
- }
-
- }
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(-200,-200,400,400);//创建一个场景
- QGraphicsEllipseItem item1(50,50,100,100);//圆项目
- scene.addItem(&item1);
-
- MyView view;//创建视图
- view.setScene(&scene);//添加场景
- view.show();
- return a.exec();
- }
点击圆项目:
在QGraphicsItem中可以使用 setZValue()函数来设置堆叠的优先级,数值越大优先级越高,默认为0。
注意:优先级相同的话,后绘制的图形会覆盖先绘制的图形
优先级相同的情况:
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsEllipseItem item1(50,50,100,100);//圆项目
- item1.setBrush(QColor(Qt::red));//红色
- scene.addItem(&item1);
- QGraphicsEllipseItem item2(75,75,100,100);//圆项目
- item2.setBrush(QColor(Qt::blue));//蓝色
- scene.addItem(&item2);
-
- QGraphicsView view;
- view.setScene(&scene);//添加场景
- view.show();
- return a.exec();
- }
设置覆盖优先级:
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsEllipseItem item1(50,50,100,100);//圆项目
- item1.setBrush(QColor(Qt::red));
- item1.setZValue(1);//设置覆盖优先级
- scene.addItem(&item1);
- QGraphicsEllipseItem item2(75,75,100,100);//圆项目
- item2.setBrush(QColor(Qt::blue));
- scene.addItem(&item2);
-
- QGraphicsView view;
- view.setScene(&scene);//添加场景
- view.show();
- return a.exec();
- }
QGraphicsItem可以设置父项目,使用setParentItem()函数可以将一个项设置成另一个项的父项。如果此项目已有父项,则首先将其从上一个父项中删除。
parentItem() | 返回父项 |
parentObject() | 返回指向项的父项的指针,强制转换为 QGraphicsObject |
parentWidget() | 返回指向项的父构件的指针。项目的父微件是最接近的父微件 |
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(0,0,400,400);//创建一个场景
- QGraphicsEllipseItem item1(75,75,100,100);//圆项目
- item1.setBrush(QColor(Qt::red));
- scene.addItem(&item1);
- QGraphicsEllipseItem item2(75,75,200,200);//圆项目
- item2.setBrush(QColor(Qt::blue));
- scene.addItem(&item2);
-
- item1.setParentItem(&item2);//设置父项
-
- QGraphicsView view;
- view.setScene(&scene);//添加场景
- view.show();
- return a.exec();
- }
当场景很大时,可以使用QGraphicsView中的centerOn()函数来设置场景中的一个点或一个图形项作为视图的显示中心
未设置中心:
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(-200,-200,800,800);//创建一个场景
- QGraphicsEllipseItem item1(75,75,100,100);//圆项目
- item1.setBrush(QColor(Qt::red));
- scene.addItem(&item1);
-
- QGraphicsView view;
- view.setScene(&scene);//添加场景
- //view.centerOn(&item1);//设置中心图形项
- view.resize(400,400);
- view.show();
- return a.exec();
- }
设置中心后:
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QGraphicsScene scene(-200,-200,800,800);//创建一个场景
- QGraphicsEllipseItem item1(75,75,100,100);//圆项目
- item1.setBrush(QColor(Qt::red));
- scene.addItem(&item1);
-
- QGraphicsView view;
- view.setScene(&scene);//添加场景
- view.centerOn(&item1);//设置中心图形项
- view.resize(400,400);
- view.show();
- return a.exec();
- }
参考文档:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。