Windows Qt动态监测系统分辨率及缩放比变化

前言

Windows 显示设置中,可以修改缩放比,所有界面和文字会同比例放大或缩小,在开发桌面程序时, 实时监测Qt应用程序在不同缩放比例下的表现,可以及时调整程序界面以适应不同显示屏幕的需求。

正文

本文通过Qt相关接口实时监测系统分辨率和缩放比的变化,并通过发送信号通知UI进行处理。兼容多屏情况,会自动检测软件窗口所在的屏幕。

关键代码:

cpp 复制代码
// HighDpiHelper.h
#ifndef HIGHDPIHELPER_H
#define HIGHDPIHELPER_H

#include "qfont.h"
#include "qscreen.h"
#include <QObject>
#include <QWindow>
#include <QGuiApplication>
#include <QDebug>

/**
 * @brief The HighDpiHelper class
 * @author luoyayun361
 * 自动监测程序所在的屏幕 缩放比变化
 * 使用需要先调用 dpiHelper.setWindow(mainWindow),mainWindow是主窗口id
 */

class HighDpiHelper : public QObject
{
    Q_OBJECT

public:
    HighDpiHelper() {
        //适配多屏幕的情况,只监测程序窗口所在的屏幕
        for(auto &screen : qApp->screens()){
            connect(screen,&QScreen::logicalDotsPerInchChanged,this,[=](qreal dpi){
                if(!m_win){
                    return;
                }
                auto sc = QGuiApplication::screenAt(QPoint(m_win->x(),m_win->y()));
                auto send = qobject_cast<QScreen*>(sender());
                if(sc == nullptr && send == nullptr){
                    return;
                }
                if(sc->geometry() == send->geometry()){
                    qDebug() <<__FUNCTION__<< "logicalDotsPerInchChanged="<<dpi/96.;
                    emit dpiChanged(dpi/96.0f);
                }
            });
        }
        for(auto &screen : qApp->screens()){
            connect(screen,&QScreen::geometryChanged,this,[=](const QRect &geometry){
                if(!m_win){
                    return;
                }
                auto sc = QGuiApplication::screenAt(QPoint(m_win->x(),m_win->y()));
                auto send = qobject_cast<QScreen*>(sender());
                if(sc == nullptr && send == nullptr){
                    return;
                }
                if(sc->geometry() == send->geometry()){
                    emit screenGeometryChanged(geometry);
                }
            });
        }
    }

    Q_INVOKABLE void setWindow(QWindow *win){
        m_win = win;
    }

    //获取当前屏幕缩放比
    Q_INVOKABLE float getScreenScalingFactor() {
        auto sc = QGuiApplication::screenAt(QPoint(m_win->x(),m_win->y()));
        if(sc){
            return sc->logicalDotsPerInch() / 96.0f; // 96 dpi 是 Windows 的标准DPI,所有的缩放比都是相对于标准 DPI 的
        }
        else{
            return 1.0;
        }
    }

    //获取窗口所在的屏幕尺寸
    Q_INVOKABLE QSize getScreenAvailableSize() {
        auto sc = QGuiApplication::screenAt(QPoint(m_win->x(),m_win->y()));
        if(sc){
            return sc->availableSize();
        }
        else{
            return qApp->screens().first()->availableSize();
        }
    }

signals:
    void dpiChanged(float scaleFactor);
    void screenGeometryChanged(const QRect &geometry);
private:
    QWindow *m_win = nullptr;
};
#endif // HIGHDPIHELPER_H

如果是在QWidget项目中,可以将QWindow 改成QWidget,然后将主窗口指针传进来即可。QML项目的话 直接使用QWindow就行。附件提供了两种场景下的demo调用。

本文demo下载

相关推荐
Hello_Embed1 小时前
Windows 安装 Claude Code 并接入 模型
windows·笔记·ai编程
Muyuan19981 小时前
28.Paper RAG Agent 开发记录:修复 LLM Rerank 的解析、Fallback 与可验证性
linux·人工智能·windows·python·django·fastapi
AxureMost3 小时前
4DDiG DLL Fixe 1.0.8.2 系统DLL修复工具
windows
怣疯knight5 小时前
Windows不安装 Android Studio如何打包安卓软件
android·windows·android studio
空中海6 小时前
02. 静态逆向、Manifest 分析与 Smali 重打包
服务器·网络·windows
一拳一个娘娘腔6 小时前
告别图形化界面:基于CLI的Windows系统入侵排查与防御实战手册
windows·安全
疋瓞7 小时前
批处理_基础补充、文件和文件夹处理_02
windows
nudt_qxx7 小时前
Ubuntu 24.04/26.04 与 Windows 10/11 双系统时间不同步终极解决方案
windows·stm32·ubuntu
钱塘江渔夫8 小时前
一键式解决Windows访问github.com不了问题
windows·github
AxureMost8 小时前
FileOptimizer 17.10.2857 文件压缩工具
windows