Item(图元)坐标系、Scene(场景)坐标系、View(视图)坐标系,三者均为:x轴正方向向右,y轴正方向向下
1、Item(图元):坐标属于局部坐标,通常以图元中心为原点(中心对称)。
场景坐标系统描述了顶层的图元,每个图元都有场景坐标和相应的包容框。
Item有setPos成员函数,设置的是父类坐标系的坐标,即此Item原点在Scene中所处的坐标。有scenePos成员函数,获取到的是setPos的设置值,默认是(0, 0)。
QGraphicsItemGroup是Qt框架中的一个类,它允许开发者将多个QGraphicsItem对象组合成一个单一的项。这种组合可以简化对这些项的操作,例如一起移动、旋转或缩放它们。QGraphicsItemGroup非常适合于那些需要将多个图形元素视为一个整体进行管理的场景,比如在绘图应用程序或游戏开发中。
2、Scene(场景):坐标属于逻辑坐标logical coordinates(与QPainter相同),以场景中心为原点。
Sence构造函数可以不带参,例如QGraphicsScene scene;可以带参,例如QGraphicsScene scene(-400, -300, 800, 600),这样定义的 scene 是左上角坐标为(-400, -300),宽度为800,高度为600 的矩形区域,单位是像素。或者可以直接使用成员函数setSceneRect设置。
3、View(视图):坐标属于设备坐标device coordinates(与窗口相同),默认以左上点为原点。
QGraphicsView类继承自QWidget类,因此它与其他的QWidget类一样,以窗口的左上角作为自己坐标系的原点。
测试发现:默认场景坐标原点与视图窗口中心对齐显示。默认视图窗口不出现滚动条,当设置的场景尺寸大于视图窗口尺寸时,出现滚动条。
4、Scene 的坐标原点与View的坐标原点之间的关系
如果设置为
_graphicsView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
没有下面这句话
_graphicsSence->setSceneRect(-100,-100,100,100)
那么scene 的坐标原点与view的坐标原点重合
如果有下面那句话,
那么view的坐标原点是 scene 的(-100,-100)
如果设置为默认的_graphicsView->setAlignment(Qt::AlignCenter)
会尽量将scene中的item作为一个组合整体。
然后找到这个组合整体的重心,放在view窗体的中心。
scene的原点,相对偏移
附一些测试代码:
//#include "mainwindow.h"
//#include <QApplication>
//int main(int argc, char *argv[])
//{
// QApplication a(argc, argv);
// MainWindow w;
// w.show();
// return a.exec();
//}
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QFileDialog>
#include "math.h"
#define M_PI 3.141592654
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene; // 定义一个场景,设置背景色为红色
//QGraphicsScene scene(-1000, -1000, 2000, 2000); // 定义一个场景,设置背景色为红色
//QGraphicsScene scene(-400, -400, 800, 800); // 定义一个场景,设置背景色为红色
scene.setBackgroundBrush(Qt::red);
QPen pen; // 定义一个画笔,设置画笔颜色和宽度
pen.setColor(QColor(0, 160, 230));
pen.setWidth(10);
QGraphicsRectItem *m_rectItem = new QGraphicsRectItem(); // 定义一个矩形图元
m_rectItem->setRect(0, 0, 80, 80);
m_rectItem->setPen(pen);
m_rectItem->setBrush(QBrush(QColor(255, 0, 255)));
m_rectItem->setFlag(QGraphicsItem::ItemIsMovable);
QGraphicsLineItem *m_lineItem = new QGraphicsLineItem(); // 定义一个直线图元
m_lineItem->setLine(QLineF(0, 0, 100, 100));
m_lineItem->setPen(pen);
m_lineItem->setFlag(QGraphicsItem::ItemIsMovable);
QGraphicsPathItem *m_pathItem = new QGraphicsPathItem(); // 定义一个路径图元
QPainterPath path;
path.moveTo(90, 50);
for (int i = 1; i < 5; ++i)
{
path.lineTo(50 + 40 * cos(0.8 * i * M_PI), 50 + 40 * sin(0.8 * i * M_PI));
}
path.closeSubpath();
m_pathItem->setPath(path);
m_pathItem->setPen(pen);
m_pathItem->setFlag(QGraphicsItem::ItemIsMovable);
QGraphicsPolygonItem *m_polygonItem = new QGraphicsPolygonItem(); // 定义一个多边形图元
QPolygonF polygon;
polygon << QPointF(-100.0, -150.0) << QPointF(-120.0, 150.0)
<< QPointF(320.0, 160.0) << QPointF(220.0, -140.0);
m_polygonItem->setPolygon(polygon);
m_polygonItem->setPen(pen);
m_polygonItem->setFlag(QGraphicsItem::ItemIsMovable);
// 使用无参构造函数创建一个 QGraphicsPixmapItem 对象
QGraphicsPixmapItem *m_pixmapItem = new QGraphicsPixmapItem(nullptr);
m_pixmapItem->setFlag(QGraphicsItem::ItemIsMovable);
QPixmap pixmap;
QString fileName = QFileDialog::getOpenFileName(
NULL, "open image file",
".",
"Image files (*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm);;All files (*.*)");
if(fileName != "")
{
// 加载一个 QPixmap 图像
pixmap.load(fileName);
// 按比例缩放
//pixmap = pixmap.scaledToWidth(500);
// 为已创建的 QGraphicsPixmapItem 设置图像
m_pixmapItem->setPixmap(pixmap);
}
m_rectItem->setPos(-200, -200);
QPointF p1 = m_rectItem->scenePos();
m_lineItem->setPos(200, 200);
QPointF p2 = m_lineItem->scenePos();
m_pathItem->setPos(200, -200);
QPointF p3 = m_pathItem->scenePos();
m_polygonItem->setPos(-200, 200);
QPointF p4 = m_polygonItem->scenePos();
m_pixmapItem->setPos(0, 0);
QPointF p5 = m_pixmapItem->scenePos();
//scene.addItem(m_rectItem); // 把矩形图元添加到场景
//scene.addItem(m_lineItem); // 把直线图元添加到场景
//scene.addItem(m_pathItem); // 把路径图元添加到场景
//scene.addItem(m_polygonItem); // 把多边形图元添加到场景
scene.addItem(m_pixmapItem); // 把图形图元添加到场景
QGraphicsView view;
m_pixmapItem->setScale(0.1);
QPointF pointScene = m_pixmapItem->mapToScene(m_pixmapItem->pos());
QPointF pointView = view.mapFromScene(pointScene);
view.setScene(&scene);
Qt::Alignment al = view.alignment();//默认的Qt::AlignCenter
view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
//QGraphicsView view(&scene); // 定义一个视图,并把场景添加到视图
view.resize(1200, 800);
view.show();
QRectF r1 = scene.sceneRect();
QRectF r2 = view.sceneRect();
QSize s1 = view.size();
return a.exec();
}