当前位置:   article > 正文

Qt获取屏幕DPI缩放比_logicaldotsperinchchanged

logicaldotsperinchchanged

获取屏幕缩放比

网上很多代码是用 logicalDotsPerInch 除以 96 来获取屏幕缩放比:

  1. // Windows 除以 96,macOS 除以 72
  2. qreal factor = window->screen()->logicalDotsPerInch() / 96.0;

当使能了缩放适配后,logicalDotsPerInch 值就不随系统缩放变了:

  1. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  2. // Qt6 默认开启缩放
  3. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  4. QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
  5. #endif

如果是 PassThrough 支持小数的设置,此时可以用 QScreen 的 devicePixelRatio 获取缩放比。

很明显,我们需要更通用的方式。通过查看源码,发现其实 Qt 内部是有对应接口的,比如 QHighDpiScaling 类的接口:

  1. qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen)
  2. {
  3. // Determine if physical DPI should be used
  4. static const bool usePhysicalDpi = qEnvironmentVariableAsBool(usePhysicalDpiEnvVar, false);
  5. // Calculate scale factor beased on platform screen DPI values
  6. qreal factor;
  7. QDpi platformBaseDpi = screen->logicalBaseDpi();
  8. if (usePhysicalDpi) {
  9. QSize sz = screen->geometry().size();
  10. QSizeF psz = screen->physicalSize();
  11. qreal platformPhysicalDpi = ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5);
  12. factor = qreal(platformPhysicalDpi) / qreal(platformBaseDpi.first);
  13. } else {
  14. const QDpi platformLogicalDpi = QPlatformScreen::overrideDpi(screen->logicalDpi());
  15. factor = qreal(platformLogicalDpi.first) / qreal(platformBaseDpi.first);
  16. }
  17. return factor;
  18. }

其中  usePhysicalDpi 一般我们也用不到,所以可以直接用 else 部分的逻辑。不过这里用到了 QPlatformScreen 类,需要引入 gui-private 模块:

  1. QT += core gui widgets
  2. QT += gui-private

简单的测试:

  1. void MainWindow::calcDpi()
  2. {
  3. // 可以从 QWidget 或者 QWindow 拿到 QScreen 对象
  4. QScreen *cur_screen = this->screen();
  5. qDebug()<<__FUNCTION__<<cur_screen;
  6. if (cur_screen) {
  7. // 逻辑 dpi (logicalBaseDpi().first) 默认值 win 96/ mac 72
  8. const QDpi base_dpi = cur_screen->handle()->logicalBaseDpi();
  9. const QDpi logic_dpi = QPlatformScreen::overrideDpi(cur_screen->handle()->logicalDpi());
  10. // 得到屏幕缩放百分比
  11. const qreal factor = qreal(logic_dpi.first) / qreal(base_dpi.first);
  12. qDebug()<<"calc dpi"<<factor;
  13. }
  14. }

关联屏幕设置变化

当在多个屏幕拖动,或者修改当前屏幕缩放比后,我们需要重新获取缩放比。

QWindow 提供了 screenChanged 信号可以感知屏幕切换。

QScreen 提供了 physicalDotsPerInchChanged 和 logicalDotsPerInchChanged 信号可以感知分辨率变化。

在 Widgets 中的大致代码就是:

  1. void MainWindow::initWindow()
  2. {
  3. qDebug()<<this->winId();
  4. // 构造的时候 windowHandle 还未初始化,可以等 show 的时候关联,或者先调用一次 winId
  5. connect(this->windowHandle(), &QWindow::screenChanged, this, &MainWindow::onScreenChange);
  6. calcDpi();
  7. }
  8. void MainWindow::onScreenChange(QScreen *screen)
  9. {
  10. // QMetaObject::Connection 保存连接便于释放;
  11. if (logicalDpiConnection) {
  12. disconnect(physicalDpiConnection);
  13. disconnect(logicalDpiConnection);
  14. }
  15. if (screen) {
  16. // 切换缩放比时,EnableHighDpiScaling 会触发 physicalDotsPerInchChanged
  17. // 此时 Qt6 不触发 logicalDotsPerInchChanged
  18. physicalDpiConnection = connect(screen, &QScreen::physicalDotsPerInchChanged, this, &MainWindow::calcDpi);
  19. logicalDpiConnection = connect(screen, &QScreen::logicalDotsPerInchChanged, this, &MainWindow::calcDpi);
  20. calcDpi();
  21. }
  22. }
  23. void MainWindow::calcDpi()
  24. {
  25. // 可以从 QWidget 或者 QWindow 拿到 QScreen 对象
  26. QScreen *cur_screen = this->screen();
  27. qDebug()<<__FUNCTION__;
  28. if (cur_screen) {
  29. // 逻辑 dpi (logicalBaseDpi().first) 默认值 win 96/ mac 72
  30. const QDpi base_dpi = cur_screen->handle()->logicalBaseDpi();
  31. const QDpi logic_dpi = QPlatformScreen::overrideDpi(cur_screen->handle()->logicalDpi());
  32. // 得到屏幕缩放百分比
  33. const qreal factor = qreal(logic_dpi.first) / qreal(base_dpi.first);
  34. qDebug()<<"calc dpi"<<factor;
  35. }
  36. }

完成示例代码

QWidget 获取 DPI 缩放:https://github.com/gongjianbo/MyTestCode/tree/master/Qt/TestQt_20231221_Dpi

QML 获取 DPI 缩放:

https://github.com/gongjianbo/MyTestCode/tree/master/Qml/TestQml_20231221_Dpi

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/94911
推荐阅读
相关标签
  

闽ICP备14008679号