自由的羽毛 发表于 2025-3-19 13:15:01

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

前言

Windows 显示设置中,可以修改缩放比,所有界面和文字会同比例放大或缩小,在开发桌面步伐时, 实时监测Qt应用步伐在不同缩放比例下的表现,可以实时调整步伐界面以适应不同显示屏幕的需求。
https://i-blog.csdnimg.cn/direct/25930d08bc0147d1bc7748e63f3cd995.png
正文

本文通过Qt相干接口实时监测系统分辨率和缩放比的变化,并通过发送信号关照UI进行处置惩罚。兼容多屏环境,会自动检测软件窗口所在的屏幕。
关键代码:
// 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下载

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Windows Qt动态监测系统分辨率及缩放比变化