当前位置: 首页 > news >正文

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&#xf…...

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&#xff0c;免去国内网络环境的干扰。 2 环境 2.1 环境 版本信息如下&#xff1a; a、操作系统&#xff1a;centos 7.9 c、docker版本&#xff1a;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分&#xff08;python、java、c、js、c&#xff09;】 题目 给一个正整数NUM1&#xff0c;计算出新正整数NUM2&#xff0c;NUM2为NUM1中移除N位数字后的结果&#xff0c;需要使得NUM2的值最小 输入描述 输入的第一行为一个字符串&#xff0c;字…...

快速搭建GPU环境 | docker、k8s中使用gpu

目录 一、裸机部署安装 GPU Driver安装 CUDA Toolkit测试 二、Docker 环境安装 nvidia-container-toolkit配置使用该 runtime 三、 k8s 环境安装 device-plugin安装 GPU 监控 一、裸机部署 裸机中要使用上 GPU 需要安装以下组件&#xff1a; GPU DriverCUDA Toolkit 二者的关…...

VSCode设置——通过ctrl+鼠标滚动改变字体大小(新版本的vs)

"editor.mouseWheelZoom": true 第一步&#xff1a; 第二步&#xff1a;...

【kafka实战】06 kafkaTemplate java代码使用示例

在 Spring Boot 中使用 KafkaTemplate 可以方便地向 Kafka 发送消息。下面为你详细介绍使用步骤和示例代码。 1. 创建 Spring Boot 项目 你可以使用 Spring Initializr&#xff08;https://start.spring.io/ &#xff09;来创建一个新的 Spring Boot 项目&#xff0c;添加以下…...

Java 23新特性

文章目录 Java 23新特性一、引言二、Markdown文档注释&#xff08;JEP 467&#xff09;示例 三、ZGC&#xff1a;默认的分代模式&#xff08;JEP 474&#xff09;1. 为什么要引入分代模式2. 使用分代模式的优势3. 如何启用分代模式 四、隐式声明的类和实例主方法&#xff08;JE…...

bat脚本实现自动化漏洞挖掘

bat脚本 BAT脚本是一种批处理文件&#xff0c;可以在Windows操作系统中自动执行一系列命令。它们可以简化许多日常任务&#xff0c;如文件操作、系统配置等。 bat脚本执行命令 echo off#下面写要执行的命令 httpx 自动存活探测 echo off httpx.exe -l url.txt -o 0.txt nuc…...

[创业之路-285]:《产品开发管理-方法.流程.工具 》-1- IPD的功能列表以及导入步骤

一、概述&#xff1a; 对于没有IPD&#xff08;集成产品开发&#xff09;流程的公司来说&#xff0c;导入IPD需要循序渐进、有序进行&#xff0c;而不是一步到位。这是因为IPD不仅仅是一种新的产品开发流程&#xff0c;它还涉及到公司文化、组织结构、团队协作方式以及思维方式…...

Redis命令:列表模糊删除详解

前言 在Redis中&#xff0c;列表&#xff08;List&#xff09;是一种非常常用的数据结构&#xff0c;允许存储多个有序的元素。然而&#xff0c;在实际应用中&#xff0c;可能会遇到需要删除列表中符合某种模式的元素的需求。本文将详细介绍如何在Redis中实现列表的模糊删除。…...

Day36-【13003】短文,数组的行主序方式,矩阵的压缩存储,对称、三角、稀疏矩阵和三元组线性表,广义表求长度、深度、表头、表尾等

文章目录 本次课程内容第四章 数组、广义表和串第一节 数组及广义表数组的基本操作数组的顺序存储方式-借用矩阵行列式概念二维数组C语言对应的函数-通常行主序方式 矩阵的压缩存储对称矩阵和三角矩阵压缩存储后&#xff0c;采用不同的映射函数稀疏矩阵-可以构成三元组线性表三…...

大数据sql查询速度慢有哪些原因

1.索引问题 可能缺少索引&#xff0c;也有可能是索引不生效 2.连接数配置&#xff1a;连接数过少/连接池比较小 连接数过 3.sql本身有问题&#xff0c;响应比较慢&#xff0c;比如多表 4.数据量比较大 -这种最好采用分表设计 或分批查询 5.缓存池大小 可能是缓存问题&#xff…...

文件 I/O 和序列化

文件I/O C#提供了多种方式来读写文件&#xff0c;主要通过System.IO命名空间中的类来实现&#xff0c;下方会列一些常用的类型&#xff1a; StreamReader/StreamWriter&#xff1a;用于以字符为单位读取或写入文本文件。 BinaryReader/BinaryWriter&#xff1a;用于以二进制格…...

机器学习中的关键概念:通过SKlearn的MNIST实验深入理解

欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 sklearn相关介绍 Scikit-learn 是一个广泛使用的开源机器学习库&#xff0c;提供了简单而高效的数据挖掘和数据分析工具。它建立在 NumPy、SciPy 和 matplotlib 等科学计算库之上&#xff0c;支持…...

HELLOCTF反序列化靶场全解

level 2 <?php/* --- HelloCTF - 反序列化靶场 关卡 2 : 类值的传递 --- HINT&#xff1a;尝试将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、结构体的简介 结构体&#xff08;Struct&#xff09;是编程语言中常见的一种复合数据类型&#xff0c;它将不同类型的数据元素&#xff08;成员&#xff09;组合成一个单一的实体。通过结构体&#xff0c;程序员可以将具有不同类型和性质的信息绑定到一个对象中&#xff0c…...

版本控制的重要性及 Git 入门

版本控制&#xff1a;软件开发的基石 在软件开发的浩瀚宇宙中&#xff0c;版本控制无疑是那颗最为闪耀的恒星&#xff0c;照亮了整个开发过程&#xff0c;成为现代软件开发不可或缺的基石。 历史追溯&#xff0c;定位问题根源 版本控制就像是一位不知疲倦的史官&#xff0c;…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...