Qt跨屏窗口的一个Bug及解决方案
如果我们希望一个窗口覆盖用户的整个桌面,此时就要考虑用户有多个屏幕的场景(此窗口要横跨多个屏幕),由于每个屏幕的分辨率和缩放比例可能是不同的,Qt底层在为此窗口设置缩放比例(DevicePixelRatio)时出了问题。
复现环境:
-
屏幕A:最大可用分辨率:3840*2160
-
屏幕A:当前设置分辨率:2048*1080
-
屏幕A:缩放比例:100%
-
屏幕B:最大可用分辨率:2560*1440
-
屏幕B:当前设置分辨率:2560*1440
-
屏幕B:缩放比例:125%
注:其他条件不变的情况下:只要屏幕A的当前设置分辨率比B小,均会出错;其他条件不变的情况下:只要屏幕A的当缩放比例与B不同,亦均会出错。
复现步骤:
1、设置窗口跨屏的代码
window->setFlags(window->flags() | Qt::FramelessWindowHint);
auto hwnd = (HWND)window->winId();
auto x = GetSystemMetrics(SM_XVIRTUALSCREEN);
auto y = GetSystemMetrics(SM_YVIRTUALSCREEN);
auto w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
auto h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
SetWindowPos(hwnd,HWND_TOP, x, y, w, h, SWP_NOZORDER );
PostMessage(hwnd, WM_DISPLAYCHANGE, 0, 0);
2、为用户桌面拍照(把这个照片显示在窗口中,照片布满整个窗口,就能只管的看出此Bug)
HDC hScreen = GetDC(NULL);
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
DeleteObject(SelectObject(hDC, hBitmap));
BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x, y, SRCCOPY);
img = QImage(w, h, QImage::Format_ARGB32);
BITMAPINFO bmi = { sizeof(BITMAPINFOHEADER), (long)w, 0 - (long)h, 1, 32, BI_RGB, (DWORD)w * 4 * h, 0, 0, 0, 0 };
GetDIBits(hDC, hBitmap, 0, h, img.bits(), &bmi, DIB_RGB_COLORS);
DeleteDC(hDC);
DeleteObject(hBitmap);
ReleaseDC(NULL, hScreen);
注:这段代码中img就是拍照后得到的QImage对象,如何把图像渲染到窗口中的代码就不写了。
这是出错时的样子:
(如你所见,左边屏幕的内容已经侵入右边屏幕去了)
这是正常时的样子:

问题影响范围
这个问题自 Qt5.x.x 到前天刚发布的 Qt6.8.2 一直存在。
无论是 Qt Widgets 窗口还是 Qt Quick 窗口,都有这个问题。
解决方案(思路)
如果是 Qt Widgets窗口 ,那么你就直接用系统API来创建窗口:
hwnd = CreateWindowEx(exStyle,
L"ScreenCapture", L"ScreenCapture",
style,x, y, w, h,
NULL, NULL, hinstance,
NULL);
然后把 QImage 渲染到这个原生窗口中:
if (img.isNull()) return;
HDC hdc = GetDC(hwnd);
auto compDC = CreateCompatibleDC(NULL);
auto bitmap = CreateCompatibleBitmap(hdc, w, h);
DeleteObject(SelectObject(compDC, bitmap));BITMAPINFO info = { sizeof(BITMAPINFOHEADER), w, 0 - h, 1, 32, BI_RGB, w * 4 * h, 0, 0, 0, 0 };
SetDIBits(hdc, bitmap, 0, h, img.bits(), &info, DIB_RGB_COLORS);
BLENDFUNCTION blend = { .BlendOp{AC_SRC_OVER}, .SourceConstantAlpha{255}, .AlphaFormat{AC_SRC_ALPHA} };
POINT pSrc = { 0, 0 };
SIZE sizeWnd = { w, h };
UpdateLayeredWindow(hwnd, hdc, NULL, &sizeWnd, compDC, &pSrc, NULL, &blend, ULW_ALPHA);
ReleaseDC(hwnd, hdc);DeleteDC(compDC);
DeleteObject(bitmap);
然后所有的绘图操作都在这个QImage上进行。
如果是 Qt Quick 窗口,那么就要用 QQuickRenderControl 来把QML内容渲染到原生窗口中了,代码过于复杂,这里就不贴了,详情请参考:https://doc.qt.io/qt-6/qquickrendercontrol.html
总之:就是不要让Qt帮我创建窗口。
相关文章:
Qt跨屏窗口的一个Bug及解决方案
如果我们希望一个窗口覆盖用户的整个桌面,此时就要考虑用户有多个屏幕的场景(此窗口要横跨多个屏幕),由于每个屏幕的分辨率和缩放比例可能是不同的,Qt底层在为此窗口设置缩放比例(DevicePixelRatio…...
Vue WebSocket简单应用 ws
webSocket应用 <template><div></div> </template><script> import { getToken } from "/utils/auth"; export default {data() {return {url: "",Socket: null, //socket对象lockReconnect: false, //锁定拒绝重连close: …...
快速单机部署ollama v0.5.7 +openwebui(免去网络环境干扰)
1 概述 本文介绍在一台机器上快速部署测试ollama和openwebui,免去国内网络环境的干扰。 2 环境 2.1 环境 版本信息如下: a、操作系统:centos 7.9 c、docker版本:20.10.5-3 3 部署 3.1 安装docker yum install -y yum-util…...
【华为OD-E卷 - 114 找最小数 100分(python、java、c++、js、c)】
【华为OD-E卷 - 找最小数 100分(python、java、c、js、c)】 题目 给一个正整数NUM1,计算出新正整数NUM2,NUM2为NUM1中移除N位数字后的结果,需要使得NUM2的值最小 输入描述 输入的第一行为一个字符串,字…...
快速搭建GPU环境 | docker、k8s中使用gpu
目录 一、裸机部署安装 GPU Driver安装 CUDA Toolkit测试 二、Docker 环境安装 nvidia-container-toolkit配置使用该 runtime 三、 k8s 环境安装 device-plugin安装 GPU 监控 一、裸机部署 裸机中要使用上 GPU 需要安装以下组件: GPU DriverCUDA Toolkit 二者的关…...
VSCode设置——通过ctrl+鼠标滚动改变字体大小(新版本的vs)
"editor.mouseWheelZoom": true 第一步: 第二步:...
【kafka实战】06 kafkaTemplate java代码使用示例
在 Spring Boot 中使用 KafkaTemplate 可以方便地向 Kafka 发送消息。下面为你详细介绍使用步骤和示例代码。 1. 创建 Spring Boot 项目 你可以使用 Spring Initializr(https://start.spring.io/ )来创建一个新的 Spring Boot 项目,添加以下…...
Java 23新特性
文章目录 Java 23新特性一、引言二、Markdown文档注释(JEP 467)示例 三、ZGC:默认的分代模式(JEP 474)1. 为什么要引入分代模式2. 使用分代模式的优势3. 如何启用分代模式 四、隐式声明的类和实例主方法(JE…...
bat脚本实现自动化漏洞挖掘
bat脚本 BAT脚本是一种批处理文件,可以在Windows操作系统中自动执行一系列命令。它们可以简化许多日常任务,如文件操作、系统配置等。 bat脚本执行命令 echo off#下面写要执行的命令 httpx 自动存活探测 echo off httpx.exe -l url.txt -o 0.txt nuc…...
[创业之路-285]:《产品开发管理-方法.流程.工具 》-1- IPD的功能列表以及导入步骤
一、概述: 对于没有IPD(集成产品开发)流程的公司来说,导入IPD需要循序渐进、有序进行,而不是一步到位。这是因为IPD不仅仅是一种新的产品开发流程,它还涉及到公司文化、组织结构、团队协作方式以及思维方式…...
Redis命令:列表模糊删除详解
前言 在Redis中,列表(List)是一种非常常用的数据结构,允许存储多个有序的元素。然而,在实际应用中,可能会遇到需要删除列表中符合某种模式的元素的需求。本文将详细介绍如何在Redis中实现列表的模糊删除。…...
Day36-【13003】短文,数组的行主序方式,矩阵的压缩存储,对称、三角、稀疏矩阵和三元组线性表,广义表求长度、深度、表头、表尾等
文章目录 本次课程内容第四章 数组、广义表和串第一节 数组及广义表数组的基本操作数组的顺序存储方式-借用矩阵行列式概念二维数组C语言对应的函数-通常行主序方式 矩阵的压缩存储对称矩阵和三角矩阵压缩存储后,采用不同的映射函数稀疏矩阵-可以构成三元组线性表三…...
大数据sql查询速度慢有哪些原因
1.索引问题 可能缺少索引,也有可能是索引不生效 2.连接数配置:连接数过少/连接池比较小 连接数过 3.sql本身有问题,响应比较慢,比如多表 4.数据量比较大 -这种最好采用分表设计 或分批查询 5.缓存池大小 可能是缓存问题ÿ…...
文件 I/O 和序列化
文件I/O C#提供了多种方式来读写文件,主要通过System.IO命名空间中的类来实现,下方会列一些常用的类型: StreamReader/StreamWriter:用于以字符为单位读取或写入文本文件。 BinaryReader/BinaryWriter:用于以二进制格…...
机器学习中的关键概念:通过SKlearn的MNIST实验深入理解
欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 sklearn相关介绍 Scikit-learn 是一个广泛使用的开源机器学习库,提供了简单而高效的数据挖掘和数据分析工具。它建立在 NumPy、SciPy 和 matplotlib 等科学计算库之上,支持…...
HELLOCTF反序列化靶场全解
level 2 <?php/* --- HelloCTF - 反序列化靶场 关卡 2 : 类值的传递 --- HINT:尝试将flag传递出来~# -*- coding: utf-8 -*- # Author: 探姬 # Date: 2024-07-01 20:30 # Repo: github.com/ProbiusOfficial/PHPSerialize-labs # email: adminhello-ctf.com…...
十二、Docker Compose 部署 SpringCloudAlibaba 微服务
一、部署基础服务 0、项目部署结构 项目目录结构如下: /home/zhzl_hebei/ ├── docker-compose.yml └── geochance-auth/└── Dockerfile└── geochance-auth.jar └── geochance-system/└── Dockerfile└── geochance-system.jar └── geochance-gateway/…...
VUE之插槽
1、默认插槽 <template><div class"father"></div><h3>父组件</h3><div class"content"><Category title"热门游戏列表"><ul><li v-for"g in games" :key"g.id">{{…...
4. Go结构体使用
1、结构体的简介 结构体(Struct)是编程语言中常见的一种复合数据类型,它将不同类型的数据元素(成员)组合成一个单一的实体。通过结构体,程序员可以将具有不同类型和性质的信息绑定到一个对象中,…...
版本控制的重要性及 Git 入门
版本控制:软件开发的基石 在软件开发的浩瀚宇宙中,版本控制无疑是那颗最为闪耀的恒星,照亮了整个开发过程,成为现代软件开发不可或缺的基石。 历史追溯,定位问题根源 版本控制就像是一位不知疲倦的史官,…...
效率提升:基于快马平台为dc=y103pc=类参数快速打造调试工具
效率提升:基于快马平台为dcy103&pc类参数快速打造调试工具 在日常开发中,我们经常需要处理各种URL参数,尤其是类似"dcy103&pctest"这样的查询字符串。手动解析和修改这些参数不仅效率低下,还容易出错。最近我在…...
成为技术专家的捷径?不,只有长期主义的坚持
在软件测试领域,我们常常被一种“速成”的幻象所包围。铺天盖地的培训广告承诺“三个月精通自动化测试”、“六周成为性能测试专家”,各种“一招鲜”的测试工具和“万能”的测试框架被包装成通往成功的捷径。对于身处其中、渴望突破职业瓶颈的测试工程师…...
(全网最全)分享8款AI工具,毕业论文AIGC率速降至5%!
【CSDN AI底层算法专栏 / 核心摘要】 2026年,学术圈的反AI审查已经演变成了一场“算法级别的军备竞赛”。随着知网、万方全面接入大模型语义探针,靠改同义词、甚至靠传统Prompt洗稿的套路已全线崩溃。为了帮大家避坑,本期专栏我从代码和算法逻…...
Ubuntu 22.04上,用Cephadm 17.2.0搭建单节点Ceph集群的保姆级避坑指南
Ubuntu 22.04单节点Ceph集群实战:从零到生产级部署的17个关键细节 当你在Ubuntu 22.04上尝试用Cephadm搭建单节点Ceph集群时,是否遇到过这些场景:bootstrap卡在某个步骤超过半小时、OSD设备明明存在却显示"no available devices"、…...
OpenProject:构建高效团队协作的终极开源项目管理平台
OpenProject:构建高效团队协作的终极开源项目管理平台 【免费下载链接】openproject OpenProject is the leading open source project management software. 项目地址: https://gitcode.com/GitHub_Trending/op/openproject OpenProject 是一款领先的开源项…...
Android TTS开发避坑指南:为什么你的Google语音引擎播不出中文?从初始化到语音包管理的完整解决方案
Android TTS开发实战:解决Google语音引擎中文播报的7个关键问题 在移动应用开发中,文字转语音(TTS)功能正变得越来越重要。从无障碍辅助功能到语音导航、有声阅读,TTS技术为应用增添了更丰富的交互维度。然而,许多Android开发者在…...
别再为Block Design里Bram深度改不了发愁了!手把手教你用Address Editor搞定(附深度换算详解)
突破Block Design中Bram深度修改困境:Address Editor实战指南 在FPGA开发过程中,Block Design的可视化设计方式极大提升了开发效率,但同时也隐藏着一些让开发者困惑的"陷阱"。其中,Bram IP核深度参数无法直接修改的问题…...
用ZYNQ PS-SPI给Flash测个速:华邦W25Q80在25MHz时钟下的真实读写性能报告
ZYNQ PS-SPI Flash性能深度评测:华邦W25Q80在25MHz时钟下的极限挖掘 当我们需要在嵌入式系统中选择一款Flash存储器时,数据手册上的理论参数往往无法反映真实应用场景下的性能表现。本文将基于Xilinx ZYNQ平台的PS-SPI接口,对华邦W25Q80 Flas…...
让AI成为开发伙伴:调用快马模型为养龙虾系统添加智能预测与问答功能
最近在开发一个养龙虾的智能决策系统,发现很多功能模块如果纯手写会非常耗时。尝试用AI辅助开发后,效率提升了不少,这里分享下具体实现思路和踩坑经验。 生长预测模块的实现 这个模块需要根据历史水温、投喂量等数据预测龙虾未来一周的生长情…...
Phi-3-mini-4k-instruct-gguf作品展:面向开发者的技术文档摘要生成样例
Phi-3-mini-4k-instruct-gguf作品展:面向开发者的技术文档摘要生成样例 1. 模型简介 Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本。这个经过优化的模型特别适合处理问答、文本改写、摘要整理和简短创作等任务。作为开发者工具&…...
