适配高DPI QWidget::move移动有错误?

news2024/11/27 8:45:36

适配高DPI QWidget::move移动有错误?

在这里插入图片描述

1、现象

在适配高DPI文章发布之后,有个小伙伴立马联系我说增加了这个特性之后,发现一个移动坐标的问题。

比如说:QWidget::move(500, 500),在实际的高DPI屏幕上移动的像素并不是QPoint(500, 500),而是比QPoint(500, 500)要大。

我觉得挺有意思,立马就写个demo测试下,果然如他所说的。

同理我测试了QWidget::setGeometry()也是这样的。

这个现象还是挺奇怪的,让我们一探究竟。

2、解决方法

老规矩,我先说下解决方案。在编译的时候可能会报错,你需要在你的vs中添加头文件目录

在这里插入图片描述

#include <QtGui/5.15.2/QtGui/private/qhighdpiscaling_p.h>

BOOL g_RecalcPoint(QWidget *widget, const QRect &oldRect, QPoint &point)
{
    if (nullptr == widget || nullptr == widget->windowHandle())
    {
        return FALSE;
    }
	// 获取到缩放之后的坐标
    QRect screenAboutRect = QHighDpi::toNativePixels(oldRect, widget->windowHandle()->screen());
    // 获取缩放比例
    QHighDpiScaling::ScaleAndOrigin scale = QHighDpiScaling::scaleAndOrigin(widget->windowHandle()->screen());
    // 目标点
    QPoint x1 = QPoint(oldRect.x(), oldRect.y());
    QPoint x2 = QPoint(screenAboutRect.x(), screenAboutRect.y());
    if (0 == scale.factor)
        scale.factor = 1.0;
    // 缩放公式逆推
    QPoint x3 = ((scale.factor+1)*x1 - x2)/scale.factor;
    point = x3;
    return TRUE;
}

//计算高度
BOOL g_RecalcRect(QWidget *widget, const QRect &oldRect, QRect &newRect, bool updateWidget, bool updateHeight)
{
    if (nullptr == widget || nullptr == widget->windowHandle())
    {
        return FALSE;
    }

    newRect = oldRect;
    QHighDpiScaling::ScaleAndOrigin scale = QHighDpiScaling::scaleAndOrigin(widget->windowHandle()->screen());
    if (updateWidget)
    {
        newRect.setWidth(oldRect.width()/scale.factor);
    }

    if (updateHeight)
    {
        newRect.setHeight(oldRect.height()/scale.factor);
    }

    return TRUE;
}

3、原理解释

3.1公式解释

x 1 就 是 我 们 需 要 移 动 到 的 点 ( 目 标 ) , x 2 就 是 经 过 了 缩 放 的 点 , f a c t o r 就 是 缩 放 因 子 。 但 是 我 们 现 在 的 目 标 是 x 1 , 也 就 是 要 有 个 点 x 3 经 过 同 样 的 缩 放 要 能 达 到 x 1 位 置 。 本 质 上 我 就 是 把 原 来 的 缩 放 公 式 进 行 了 逆 推 。 x_1 就是我们需要移动到的点(目标),x_2就是经过了缩放的点,factor就是缩放因子。\\ 但是我们现在的目标是x_1,也就是要有个点x_3经过同样的缩放要能达到x_1位置。\\ 本质上我就是把原来的缩放公式进行了逆推。 x1x2factorx1,x3x1

{ ( x 1 − y ) × f a c t o r + y = x 2 ( x 3 − y ) × f a c t o r + y = x 1 \begin{cases} (x_1-y) \times factor + y = x_2\\ (x_3-y) \times factor + y = x1 \end{cases} {(x1y)×factor+y=x2(x3y)×factor+y=x1

解方程组得出如下的公式,就是上面的公式由来。
x 3 = ( ( 1 + f a c t o r ) × x 1 − x 2 ) f a c t o r x_3 = ((1+factor) \times x_1 - x_2) \over factor factorx3=((1+factor)×x1x2)

还有一个疑问:缩放公式我是怎么来的?

除了看源代码,没有技巧可言。

我把代码贴出来给你看下就知道了。这里的origin其实就是上面方程组的y,其实这个参数不重要,因为最后被消除掉了。

inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
     return (pos - origin) * scaleFactor + origin;
}

再提一句,为什么在g_RecalcRect中计算高度和宽度的需要oldRect.height()/scale.factor,也是根据源码的公式逆推的。

最有一个问题:我怎么就找到这里了呢?

看代码分析流程,再加上调试手段,就会定位到这里了。我把调用堆栈截图你看下就明白了。注意我这里给的QWidget::setGeometry()流程,其实QWidget::move()也是会调用QWidget::setGeometry()

在这里插入图片描述

4、总结

从现象来看是很奇怪,但是我们一旦知道原理之后,就发现这一切理所当然的。

需要深究原理,不能有懈怠之心。谜题总是会解开的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django的汽车租赁系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Linux下使用kvm搭建虚拟机群

Linux下使用kvm搭建虚拟机群 1.安装kvm 1.检查cpu是否支持虚拟化 [rootkevin ~]# grep vmx /proc/cpuinfo 如果有vmx信息输出&#xff0c;就说明支持VT;如果没有任何的输出&#xff0c;说明你的cpu不支持&#xff0c;将无法使用KVM虚拟机。 2.确保BIOS里开启虚拟化功能&…

three.js之材质

文章目录简介常用材质点材质线材质网格模型材质和模型的对应关系属性公有属性sideopacity私有属性专栏目录请点击 简介 所谓材质&#xff0c;就是平常我们所说的塑料材质&#xff0c;金属材质&#xff0c;纤维材质等实质上所有材质都是WebGL着色器代码的封装 常用材质 点材质…

2023年湖北监理工程师报考条件和专业要求有哪些? 甘建二告诉你

2023年湖北监理工程师报考条件和专业要求有哪些&#xff1f; 一、2023年湖北监理工程师报考条件详细解读&#xff1a; 1、大专毕业满足4年&#xff0c;毕业专业理工类或者工科类专业毕业&#xff0c;监理工程师分为3个专业&#xff0c;土建、交通、水利三个专业对于报考专业要…

BIM设计 | 学会CAD这5个隐藏操作,让你受益无穷

每一个CAD设计师都会有自己的设计习惯&#xff0c;无论是从CAD的绘图、改图、图层管理、图块管理、甚至是打印设置&#xff0c;都是不尽相同的。 对于还是小白的新手设计师来说&#xff0c;是还没有一套属于自己的操作习惯的&#xff0c;这个阶段大多数新手设计师都是通过参考别…

Python之多进程

python中的多线程其实并不是真正的多线程&#xff0c;如果想要充分地使用多核CPU的资源&#xff0c;在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing&#xff0c;只需要定义一个函数&#xff0c;Python会完成其他所有事情。借助这个包&…

centos安装nginx

系统版本&#xff1a;centos7.9-2009 nginx版本&#xff1a;1.20.2 1、去nginx官网下载压缩包&#xff0c;此处选择稳定版本 nginx官网链接 2、上传到服务器指定位置/opt/tools,根据个人习惯来 解压&#xff1a; tar -zxvf nginx-1.20.2.tar.gz3、配置&#xff0c;使用默认配置…

npm install 安装包时,常用的-S 、-D 、-g 有什么区别?

一、主要区别就是依赖配置写入package.json文件的位置不同而已 npm install 本身就有一个别名 npm i &#x1f449; npm i module_name -S 即 npm install module_name --save 写入dependencies&#xff0c;发布到生产环境 这样安装是局部安装的&#xff0c;会写进…

MySQL存储引擎InnoDB架构

目录 查看MySQL使用的存储引擎 磁盘文件 系统表空间 用户表空间 InnoDB逻辑存储结构 RedoLog文件 内存结构 缓冲池Buffer Pool RedoLogBuffer ChangeBuffer Double Write CheckPoint机制下的脏页落盘 RedoLog落盘 查看MySQL使用的存储引擎 sql show engines; 对于存储…

G1D26-DP presentationNLP相关

一、DP &#xff08;一&#xff09;代码 钞票问题简单写了写代码&#xff0c;对比了一下暴搜和dp的速度 二项式问题&#xff0c;对比了递归和DP (二) CPU 1、cpu&#xff0c;内核和逻辑处理器 一个CPU可以有多个内核&#xff0c;内核就是真正的物理核心&#xff0c;而往往…

Spring——@Transactional事务注解原理及失效场景

Spring——Transactional事务注解原理及失效场景一、属性介绍二、传播机制准备例子总结三、原理四、失效场景一、属性介绍 value 和 transactionManager 属性 它们两个是一样的意思。当配置了多个事务管理器时&#xff0c;可以使用该属性指定选择哪个事务管理器。 isolation…

javaSE -类(class)和对象

一、类与对象的初步认知 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 JAVA是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完成。 面向…

FT2004(D2000)开发实战之W25X10CL固件烧写

一 W25X10CL固件烧写 1.1 Windows电脑安装GZUT_EZP_XPro编程器2.0软件,安装成功后会生成如下图标 1.2 固定和安装W25X10CL芯片 W25X10CL属于典型的8PIN SPI Flash芯片,其固定和安装方法如下所示: 1.2.1 准备Flash编程器、SOP8转DIP8转换器以及Flash芯片,下图所示为Flash编…

计算ip是否在网络段(子网掩码)

比如 检查下面的ip是否在网络段内 IP 192.168.1.3 子网掩码 255.255.255.192 IP 192.168.1.3 对应的&#xff1a; 11000000.10101000.00000001.00000011 先把上面的子网掩码 255.255.255.192 转成二进制 结果应该是 11111111.11111111.11111111.11000000 这时有26个…

Vue如何实现快进后退的跑马灯组件

Vue如何实现快进后退的跑马灯组件 用vue编写一个可以快进后退的跑马灯组件 由于业务需求&#xff0c;要实现一个会可以控制速度的跑马灯&#xff0c;刚开始用js的setinterval每隔几毫秒来减取一个字符拼接到后面&#xff0c;效果不理想就放弃了。后来用animate这个api实现了。…

MyBtais的SQL映射文件(元素,查询,映射,动态SQL)

目录 1.概述 2.SQL映射文件元素 3.Mybatis框架的条件查询 3.1 单参数查询(模糊查询) 3.2 多参数查询 3.2.1 JavaBean 对象参数 3.2.2 Map 参数 3.2.3 Param 注解 参数 3.2.4 底层顺序[param1,param2] 4.Mybatis框架的结果映射 4.1 resultMap自定义映射 4.1.1 Res…

[附源码]Python计算机毕业设计Django点餐系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

一、【react-redux】react-redux 基本使用

文章目录1、react-redux模型图2、放在前面的总结3、react-redux 简单使用3.1、项目结构3.2、CODE3.2.1、containers/Count/index.jsx3.2.2、App.js3.2.3、入口 index.js3.2.4、Count_Redux.jsx由于react日常开发人们习惯使用redux做状态管理 FaceBook官方就出了一个react-redux…

关于Hbase使用出现java.io.IOException: java.lang.reflect.InvocationTargetException解决

我也不知道出错原因&#xff0c;改着改着就好了&#xff0c;所以以下解决方法可以试试&#xff0c;不保证一定有用。 出现了这样的报错&#xff1a;java.io.IOException: java.lang.reflect.InvocationTargetException 往下看Cause by 百度百度摸到这篇博客 根据上述博客所总结…

【人工智能】知识表示

目录一、知识表示&#xff08;Knowledge Representation&#xff09;的基本概念二、谓词逻辑&#xff08;Predicate Logic&#xff09;表示法三、产生式&#xff08;Production Rule&#xff09;表示法四、语义网络&#xff08;Semantic Network&#xff09;表示法五、框架&…