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

目录

一、引言

二、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/

 

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值