Qt的坐标系系统 - 3个坐标系,2个变换

参考:

  1. https://zhuanlan.zhihu.com/p/584048811
  2. https://www.zhihu.com/tardis/zm/art/634951149?source_id=1005

小谈Qt的坐标系系统

Qt中有三个坐标系

  • 设备坐标系
  • 窗口坐标系
  • 逻辑坐标系

设备坐标系: 即Device坐标系。也是物理坐标系。即真实的的物理坐标系。

逻辑坐标系: 即用户坐标系。也就是说日常大家使用Qt的时候的坐标系。

窗口坐标系: 这个坐标系是QPainter设置setWindow以后的一个坐标系。

这三个坐标系,基本上就代表了常规的绘制引擎的三个坐标系。

那么三个坐标系,就代表可以用两次变换来实现了。

这个就是QPainter中的setWindow() & setViewport()的两个概念了

直接看下图

在这里插入图片描述在这里插入图片描述via https://doc.qt.io/qt-6/coordsys.html#window-viewport-conversion

OK,既然有了这些概念,那么我们就开始讲一下,坐标系的转换流程。

废话不多说
还是按照我的方式 & Qt的官方文档来讲吧

我自己的例子

画个图,描述下这三个坐标系

在这里插入图片描述平时我们的三个坐标系都是相同的,都是水平方向是X轴,垂直方向是Y轴,坐标原点是左上角(0, 0)。

X轴从左到右增加,Y轴从上到下增加

即如图所示
在这里插入图片描述那么三个坐标系的变化流程就是

在这里插入图片描述还是先上个Qt的Demo

Qt的Demo

设定,屏幕的DPI是96

三个坐标系重叠

先创建一个QWidget,然后设置其大小是(500, 500)

resize(500,500);

然后再重写他的PaintEvent事件

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.drawLine(0,0,500,500);
}

那么表现
在这里插入图片描述这里可以先重点说下
我们以普通用户(程序员)的角度来理解这个代码。因为有三个坐标系,所以Qt的代码全都是以逻辑坐标系为基础的。对于这个代码来讲

painter.drawLine(0,0,500,500);

drawLine的时候实际上就是以逻辑坐标系为准。这时候,三个坐标系是相等的,没有任何比例变化。大家可以理解为这三个坐标系是重叠的。

setWindow()
控制变量,其他的代码不变,我们只单独设置setWindow这个代码setWindow的作用,就是在物理坐标系不变的情况下,将逻辑坐标系进行缩放。

假定,我们的代码是这样的。将逻辑坐标扩大一倍,那么代码就是这样的

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.setWindow(0,0,1000,1000);
painter.drawLine(0,0,500,500);
}

这时候我们的窗口就变成了这个样子。
在这里插入图片描述也就是说,我的物理大小,并没有变,我通过更改逻辑坐标,(放大两倍的效果) 看起来将我的整个坐标系变大了。比如原来我可以通过

painter.drawLine(0,0,500,500);

来绘制对角。

经过

painter.setWindow(0,0,1000,1000)\\放大逻辑坐标系两倍

最后

painter.drawLine(0,0,500,500);\\只能绘制一半的效果。

在这里插入图片描述如果还想绘制对角,那么就得

painter.drawLine(0,0,1000,1000);

在这里插入图片描述也就是,我们现在将用户的坐标系放大了两倍。这个就是setWindow的作用。

setViewport()
大家可以理解setViewport的作用就是控制物理坐标系的。
在这里插入图片描述比如官方代码

int side=qMin(width(),height());
int x=(width()-side/2);
int y=(height()-side/2);painter.setViewport(x,y,side,side); 

还要控制窗口的宽高,这时候就更难理解了。我的例子还是控制变量,假定Window不变。我们只更改ViewPort

还是那个例子,窗口大小(500, 500)。我们还是画对角线。这时候我们把代码改成

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.setViewport(0,0,1000,1000)
painter.drawLine(0,0,250,250);
}

大家可以看现象,画线也变粗了。这是为啥呢?
在这里插入图片描述很简单,painter.setViewport(0, 0, 1000, 1000)这个代码相当于把整个物理坐标系翻倍了。也就是单位逻辑坐标变大了。

原来逻辑坐标画1个像素点,现在相当于画2个。

所以会有两个现象

  • 画线变粗
  • drawLine现在只需要一半就可以撑满整个窗口。

小结:

在这里插入图片描述还是要好好观察下这个顺序。

Qt通过三个坐标系,来做到了窗口之间的变换 & 放大缩小。

那么工程上是如何使用的呢。一般来说viewport这个跟当前物理DPI保持一致。

然后通过setWindow放大坐标系

如果你想把整个逻辑坐标系放大。那么就用setWindow()还是看你当前的逻辑需求- 即逻辑坐标系的需求。

以这个为出发点,那么再去理解setWindow & setViewport就很好理解了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/267515.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Camunda 7.x 系列【60】流程分类

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 案例演示2.1 后端2.2 前端2.3 测试1. 前言 钉钉中的OA审批分类: 企业级的业务…

Python 反编译Il2Cpp APK

引入 https://github.com/Perfare/Il2CppDumper/ 实现 开源的Ii2Cpp Dumper可以帮助我们将So和globalmetadata.dat文件反编译出 Assembly-CSharp.dll 本博客教程可以帮助我们直接拖入APK反编译出来 调用方式 两种 第一种 拖入后回车运行 第二种 放入运行的根目录下 源码 i…

【Jeecg Boot 3 - 第二天】1.2、jar 包和 lib 依赖分离,部署包缩小100倍

一、场景 二、思路 三、实战 ▶ 2.1、项目 jar 包解压获取 lib config Stage 1:正常打包获取 jeecg-system-start-3.6.0.jar Stage 2:解压 获取如下文件 Stage 3:获取 lib config ▶ 2.2、获取简化版项目jar包 Stage 1&#xff1…

【二者区别】cuda和cudatoolkit

Pytorch 使用不同版本的 cuda 由于课题的原因,笔者主要通过 Pytorch 框架进行深度学习相关的学习和实验。在运行和学习网络上的 Pytorch 应用代码的过程中,不少项目会标注作者在运行和实验时所使用的 Pytorch 和 cuda 版本信息。由于 Pytorch 和 cuda 版…

Altman作了多少恶?排挤首席科学家出GPT5开发、离间董事会、PUA员工

在山姆奥特曼(Sam Altman)被OpenAI董事会突然解职后的几天里,这个消息在科技圈引发轰动,该公司内部员工和许多科技界人士甚至将此举比作一场政变。 奥特曼被解雇后立即传出的说法是,OpenAI的广大员工都很喜欢他&#x…

mmyolo框架中计算各类别的AP@0.5指标

本文所用的mmyolo版本:0.3.0 背景: 首先要知道,mmyolo中在eval和test阶段进行指标计算的时候,对于COCO数据集默认用的就是mAP0.5:0.95,即不同IoU阈值下的mAP计算,并且没有给出各类别的具体指标,如 可以看…

c语言->自定义类型联合体和枚举类型

系列文章目录 文章目录 前言 ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青_C语言,函数,指针-CSDN博客 目的:学习联合体和枚举类型的…

Xinlinx Vivadao入门学习

#1, 引脚定义 1.1 Bank定义 1.2, 当两个banks的I/O口作为LVDS电平时,HR banks的I/O电压VCCO只能为2.5V,HP banks的I/O口电压为1.8V。两个banks支持LVDS的标准不同,HR I/O banks的I/O只能分配LVDS_25标准,…

运筹学经典问题(二):最短路问题

问题描述 给定一个图(有向图或无向图) G ( V , E ) G (V, E) G(V,E), V V V是图中点的集合, E E E是图中边的集合,图中每条边 ( i , j ) ∈ E (i, j) \in E (i,j)∈E都对应一个权重 c i j c_{ij} cij​(…

农副产品行业ERP有哪些?农副产品行业ERP是做什么的

现实生活当中有很多种类的农副产品,这些琳琅满目的商品有多元化的营销渠道和策略,同时在保质期、包装、价格策略、配料、生产工艺等诸多方面存在明显的差异。 由于行业的特殊性,传统的人工统计分析工作量较大,同时也难以确保业务…

使用Python实现阿里系某购物网站Sign参数加密

文章目录 1. 写在前面2. 抓包分析3. 断点分析4. 爬虫实现 【作者主页】:吴秋霖 【作者介绍】:Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作! 【作者推荐】:对JS逆向感兴趣的朋…

2017下半年软工(桥接模式)

题目——桥接模式(抽象调用实现部分) package org.example.桥接模式;/*** 桥接模式的核心思想是将抽象部分与它的实现部分分离,使它们可以独立变化,就是说你在实现部分:WinImp、LinuxImp基础上还能加上RedHatImp&#…