背景
在做绘图处理时,Scence作为场景,大小是无限的,而View作为一个观察镜头,观察范围是有限的。
那么有限的View观察无限的Scence区域,必然要选定一个观测锚点。
所以View具有一个centerOn(QPointF pos)函数,输入的是Scence的坐标,把SCence中位于pos的点显示在View的中心。即以Scence的pos点作为View观察的中心。
中心点坐标分析
默认情况下,View是选择ScenceRect的中心点作为观察中心的。
Scence是无限大的,但是我们作画一般是在Scence的某一区域进行的,所以可以对Scence设置一个ScenceRect,如果不设置,那么系统会计算你画的所有Item的边界并集当做ScenceRect,这样效率不高。
一般情况下,会手动给Scence设置一个ScenceRect。设置好之后,View的中心点就是这个ScenceRect的中心点。
具三个例子来说明如下:
ScenceRect比View小
view的大小为:1200*687
senceRect大小为(0,0,200,200)
QRect rect(0,0,200,200);
m_scence->setSceneRect(rect);
m_scence->addRect(rect);
m_scence->addRect(QRectF(0,0,100,100));
m_scence->addRect(QRectF(100,100,50,50));
m_scence->addItem(rectItem1);
ui->graphicsView->setScene(m_scence);
效果如下,View以SenceRect的中点(100,100)为中心点:
ScenceRect与View相等
当ScenceRect与View相等时,那么SCenceRect的中点必然就是View的中点,此时两个坐标系的远点是重合的:
ScenceRect比View大
道理同上,不再赘述。
遗留问题
资料上说,Item的原点是item的中心点,但是上面的实验中的item的原点默认都是左上角。
在Item中,setPos(pos)是指把item的位置设置到pos处,pos是scence坐标,设置好之后,item的原点(0,0)就是scence的pos。
1. 不使用setpos时
RectGraphicsItem *rectItem = new RectGraphicsItem(QRectF(20,20,150,50));
rectItem->setColor(QColor(Qt::black));
m_scence->addItem(rectItem);
指定了初始化的位置为(20,20)的矩形,此时item的默认原点坐标与Scence的原点坐标重合,所以如下所示:
2. 使用setpos时
RectGraphicsItem *rectItem = new RectGraphicsItem(QRectF(20,20,150,50));
rectItem->setColor(QColor(Qt::black));
rectItem->setPos(20,20);
m_scence->addItem(rectItem);
如上所示,设置了(20,20)的矩形后,会在Scence(20,20)的位置画一个矩形,setPos(20,20)后,会把item放到sence(40,40)的位置,此时item的原点坐标(0,0)不再与Scence重合,而是在Secence的(20,20)位置。
3. 推荐方式
如上面1和2介绍,item的内部坐标还要与父坐标系进行转换,较为复杂,在写代码绘制时,脑子要转好几个弯,造成思维混乱,为了解决这个问题,见如下代码:
//位置都从(0,0)开始
RectGraphicsItem *rectItem = new RectGraphicsItem(QRectF(0,0,150,50));
rectItem->setColor(QColor(Qt::black));
rectItem->setPos(20,20);//然后平移到sence的(20,20)位置,此时item的(0,0)就是此点
m_scence->addItem(rectItem);
- 初始化rect时,总是设置为(0,0)。
- 使用setpos设置到相应的位置(x,y),如上面的(20,20)。
- 这样,item的原点就是(x,y),对item内部来说总是以左上角(0,0)为坐标的原点,item的坐标不至于混乱。结果与1中的对比如下: