QT——逻辑坐标系setWindow与物理坐标系setViewPort

发布时间 2023-09-04 15:42:07作者: imxiangzi

目录

一、引言

二、QT坐标系与绘图总结

三、自定义逻辑坐标系

四、自定义物理坐标系

 

一、引言

看了参考博客中关于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())的放大因子。

 

 

参考:

三步理解Qt中的setViewport和setWindow

QT 坐标系理解

QT 利用QPainter绘图的坐标系转换

Qt坐标系统

QT 如何使用painter

https://www.cnblogs.com/duguochao/p/4370007.html

https://www.devbean.net/2012/11/qt-study-road-2-coordinate-system/

 

 

 

 https://blog.csdn.net/qinze5857/article/details/103652909