目录
一、引言
看了参考博客中关于QT窗口和视口的理解,获益非浅,在此做个总结和补充。
二、QT坐标系与绘图总结
QT中的painter绘制在逻辑坐标系中(该坐标系是我们自定义的,通过setWindow(int x,int y, int width,int height)),窗口与逻辑坐标系相关联,逻辑坐标系是一个坐标体系,那么窗口是在该体系的一个矩形框。窗口决定了我是看你的一部分还是整体。
不管怎么说我们都要把这个矩形框显示在屏幕中,也就是映射投影QT的绘图设备上(widget),因此就有了物理坐标系和视口。简单理解物理坐标系,是绘图设备上的坐标系(逻辑坐标系和物理坐标系默认重合,左上角是原点,向右是x轴正方向,向左是y轴正方向),通过setViewPort(int x,int y, int width,int height)定义物理坐标系统的坐标原点,也定义了视口的矩形框大小。按照“三步理解“中来讲是: 你还是别映射到我整个绘图设备,你映射到我给你的那块区域吧。
关系如何:窗口坐标为逻辑坐标,是基于视口坐标系的;视口坐标为物理坐标,是基于绘图设备坐标系的(十分关键,多多理解)。视口是窗口按比例在显示设备(如QWidget)上的投影。窗口解决内容的问题,视口解决显示的问题。只要显示区域足够大,指定的窗口外的其它内容同样也会在视口以外显示出来,本质都是基于坐标原点的偏移运算。
Okay,这一块参考中的博文自有更详细的解释,本文博文中旨在未描述的。
三、自定义逻辑坐标系
QPainter painter(this);
painter.setWindow(QRect(50,-50,100,-100));
好吧,我又把它搬出来了。
函数原型:
void QPainter::setWindow(int x, int y, int width, int height)
参数:
x:逻辑坐标系下窗口左上角x坐标
y:逻辑坐标系下窗口左上角y坐标
width:窗口长度
height:窗口高度
Width= 50-(-50) = 100;Height = -50-50 = -100;那么就是painter.setWindow(-50,50,100,-100);
可以设置为painter.setWindow(-width()/2,height()/2,width(),-height());
//以下四种操作都是对于逻辑坐标系
painter.translate(); //平移
painter.rotate(); //旋转
painter.scale(); //比例
painter.shear(); //扭曲
//示例
void PaintDemo::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(10, 10, 50, 100, Qt::red);
painter.save();
painter.translate(100, 0); // 向右平移 100px
painter.fillRect(10, 10, 50, 100, Qt::yellow);
painter.restore();
painter.save();
painter.translate(300, 0); // 向右平移 300px
painter.rotate(30); // 顺时针旋转 30 度
painter.fillRect(10, 10, 50, 100, Qt::green);
painter.restore();
painter.save();
painter.translate(400, 0); // 向右平移 400px
painter.scale(2, 3); // 横坐标单位放大 2 倍,纵坐标放大 3 倍
painter.fillRect(10, 10, 50, 100, Qt::blue);
painter.restore();
painter.save();
painter.translate(600, 0); // 向右平移 600px
painter.shear(0, 1); // 横向不变,纵向扭曲 1 倍
painter.fillRect(10, 10, 50, 100, Qt::cyan);
painter.restore();
}
另外:
painter.setWindow(-50, -50, 100, 100); //表示x,y坐标不变,可视的窗口移动到(-50,-50)的位置。同时在x,y方向产生factorX= (window.width())/100的放大因子,factorY= (window.length))/100的放大因子。
我在逻辑坐标系中画了图,最后投影到物理坐标系中,这其中起始包含了3中坐标系,两种坐标变换
世界坐标(逻辑坐标)->中间态坐标(windows坐标)->物理坐标(视口坐标)
painter.worldTransform();
painter.deviceTransform();
painter.combinedTransform() //定义了逻辑坐标点和具体的某个像素对应关系
//用法
QTransform transform; //世界变换
transform.translate(0, 0); //以00为中心 选装30°
transform.rotate(+30.0);
painter3.setWorldTransform(transform); //添加世界变换
painter3.drawPath(path);
四、自定义物理坐标系
函数原型:
void QPainter::setViewport ( int x, int y, int width, int height )
参数:
x:设置视口左上角x坐标
y::设置视口左上角y坐标
width:设置视口长度
height:设置视口宽度
painter.setViewport(50, 50, 400, 300);//表示窗口不动,(x,y)坐标移动到(50,50)的位置,且在x方向产生factorX= 400/(window.width())的放大因子。
参考:
https://www.cnblogs.com/duguochao/p/4370007.html
https://www.devbean.net/2012/11/qt-study-road-2-coordinate-system/