Qt绘图中,QGraphicsView、QGraphicsScene、QGraphicsItem三者之间密不可分,以下简单介绍三者之间关系。
三者之间关系:
如同绘画的过程,Qt绘图中,QGraphicsView的作用相当于画板,QGraphicsScene等效于画布,QGraphicsItem为画布上的画。
- 拿出画板,订上一张画布:UI中添加了一个QGraphicsView后,需要往其中添加QGraphicsScene,可以添加好几张画布。
- 拿起笔,在画布上作画:往QGraphicsScene上添加各式各样的QGraphicsItem,QGraphicsItem有很多种,最常用的是QGraphicsPixmapItem,也就是贴图到画布上;使用QPainter,可以自己亲自画线。
大致过程就如上所述,因此完成一幅图片的显示需要三个步骤:
- 将Pixmap添加至QGraphicsPixmapItem;
- 将QGraphicsPixmapItem添加至QGraphicsScene;
- 将QGraphicsScene添加至QGraphicsView;
三者间坐标关系:
若想让图片动起来或者在自定义位置显示,则不得不考虑坐标问题,三者均有自己的坐标系,坐标系原点在左上角,如图所示:
我们可以对item的元素进行旋转、缩放等操作,此时坐标系之间的关系会发生变化,话不多说,直接上程序:
//新建一个Qt Widgets Application
//在mainwindow.ui里添加一个QGraphicsView
//添加需要的头文件,在MainWindow构造函数里添加以下函数
//写在ui->setupUi(this);后
//
QGraphicsScene *scene;
QGraphicsPixmapItem *item;
QPixmap *painterPix;
scene = new QGraphicsScene;//新建一个场景
ui->graphicsView->setScene(scene);//将场景添加进视图
scene->addRect(0,0,500,500);//设置场景位置(0,0),大小500x500
//设置三个不同的方块,打印出每个方块的坐标,方块中心场景坐标,方块中心坐标
//第一个方块,黑色
item = new QGraphicsPixmapItem;//新建一个item
painterPix = new QPixmap(50,50);//新建一幅图
painterPix = fill(Qt::black);//将图设置为黑色
item->setPixmap(*painterPix);//将图添加进item
scene->addItem(item);//将item添加进场景
item->setPos(0,0);//设置item坐标为(0,0)
qDebug()<<"black pos:"<<item->pos()<<"black pixPos:"<<item->mapToParent(item->pixmap().rect().center())<<"pix cenPos:"<<item->pixmap().rect().center();
//第二个方块,蓝色,旋转90度
item = new QGraphicsPixmapItem;
painterPix = new QPixmap(50,50);
painterPix = fill(Qt::blue);
item->setPixmap(*painterPix);
scene->addItem(item);
item->setPos(50,50);
item->setRotation(90);//旋转90度
qDebug()<<"black pos:"<<item->pos()<<"black pixPos:"<<item->mapToParent(item->pixmap().rect().center())<<"pix cenPos:"<<item->pixmap().rect().center();
//第三个方块,红色,放大为原来的2倍
item = new QGraphicsPixmapItem;
painterPix = new QPixmap(50,50);
painterPix = fill(Qt::red);
item->setPixmap(*painterPix);
scene->addItem(item);
item->setPos(100,100);
item->setRotation(2);//放大两倍
qDebug()<<"black pos:"<<item->pos()<<"black pixPos:"<<item->mapToParent(item->pixmap().rect().center())<<"pix cenPos:"<<item->pixmap().rect().center();
得到结果为下图所示:
打印出来的坐标值为:
黑:(0,0),(24,24),(24,24)
蓝:(50,50),(26,74),(24,24)
红:(100,100),(148,148),(24,24)
因此得出结论:
- item的坐标即为item左上角点在scene的坐标
- item中图像中心坐标,为中心点在item坐标系下的坐标
- item中图像的坐标,不随着item自身的放大旋转的影响
- item的旋转放大等操作,均以左上角坐标为原点
最终,可以看出,要时刻记得左上角为原点,外部的坐标变化不影响内部的坐标,可以通过mapToParent等方法完成各坐标系间的坐标转换。