Qt5 高分辨率支持

这篇具有很好参考价值的文章主要介绍了Qt5 高分辨率支持。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 结论

先说结论,在Qt5版本没有比较完美的解决方案。如果使用Qt系统提供的支持方式会出现各种小问题。如果可以的,建议升级为Qt6版本,能够更好支持高分辨率屏。而最终我在Qt5.12.12版本中,采用的方案是通过各种方法组合解决。
详细可参考知乎回答目前Qt有没有比较好解决高分屏下缩放显示的方案?

2. Qt系统自带解决方案说明

2.1 设置环境缩放

  1. qputenv(“QT_AUTO_SCREEN_SCALE_FACTOR”, “2”);
  2. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

上面两种实现本质差不多。第一种设置环境参数的需要根据dpi计算缩放比例。第二种则系统自动进行缩放。该方案能够简单实现高分辨率屏的支持,如果使用建议直接使用第二种即可。
该方案的问题:在于在Qt5.14.x以下版本,只支持整数倍缩放。
Qt5 高分辨率支持

  • 在设置为100% ~ 149%范围内,Qt缩放的倍数为1。
  • 在设置为150% ~ 249%范围内,Qt缩放的倍数为2。
  • 在设置为250% ~ 349%范围内,Qt缩放的倍数为3。
  • 往后依次类推。
    这导致了当系统设置为150%,Qt程序界面会缩放成2倍,看起来效果非常的大,与系统并不协调。

2.2 使用标准配置文件

在资源qrc里添加qt.conf文件,qt/etc/qt.conf, 内容为:

[Platforms]
WindowsArguments = dpiawareness=0

这方案使得Qt程序让windows系统接管控制缩放,整体比例协调,实现简单。
缺点在于会导致界面的模糊,在我电脑测试中,效果十分模糊,个人不太接受。

2.3 结论

有条件的升级为Qt6版本,支持效果更好。无法升级的,根据实际情况选择一种接受的方案。

3. 组合方案

由于作者对于Qt自带的解决方案都不满意, 于是只好一步一步解决。

3.1 解决字体问题

所有的字体使用pt单位,不是用px单位。转换公式为 pt = px * 3 / 4,比如12px * 3 / 4 = 9pt大小。

QFont font("Microsoft YaHei");
// 小数使用
font.setPointSizeF(10.5);
// 整数使用
font.setPointSize(10);
app.setFont(font);

qss中也改为pt单位。

QMenuBar {
	background: #F6F6F6;
	font: 10.5pt;
}

pt单位的字体,系统根据分辨率缩放字体大小,详细可查看文章pt和px的区别是什么。

3.2 解决尺寸问题

获取系统当前的dpi,与96相除得到当前系统的缩放比例,ui使用dpi=96设计界面,根据尺寸进行按比例拉伸。包括layout布局的margins,spacing属性也需要同步拉伸(如果没修改过默认的layout的margins,spacing属性,Qt底层其实会自动拉伸的,不过为了方便我对全局的布局器都一同拉伸)。

/**
  * @file   style_helper.h
  */

#ifndef STYLE_HELPER_H
#define STYLE_HELPER_H

#include <QSize>

class QWidget;
class QLayout;

class StyleHelper
{
public:
  explicit StyleHelper();

  static QSize mainwindowSize();
  static QSize mainwindowSubSize();
  static QSize dialogSize();

  static qreal dpiScaled(qreal value);
  static void sizeScaled(QWidget *widget);

private:
  ///< 屏幕分辨率
  static qint32 my_window_width_;
  static qint32 my_window_height_;
  ///< 屏幕dpi值
  static qint32 my_window_dpi_;
  ///< 屏幕缩放倍数
  static qreal my_window_scale_;
};

#endif // STYLE_HELPER_H
/**
  * @file   style_helper.cpp
  */
#include <QScreen>
#include <QWidget>
#include <QLayout>
#include <qformlayout.h>
#include <QApplication>

#include "style_helper.h"


qint32 StyleHelper::my_window_width_ = 1920;
qint32 StyleHelper::my_window_height_ = 1080;
qint32 StyleHelper::my_window_dpi_ = 96;
qreal StyleHelper::my_window_scale_ = 0;

/**
 * @brief       构造函数
 */
StyleHelper::StyleHelper()
{
  QScreen *screen = QApplication::primaryScreen();
  my_window_width_ = screen->geometry().width();
  my_window_height_ = screen->geometry().height();
  my_window_dpi_ = screen->logicalDotsPerInchX();

  // ui设计使用dpi = 96
  my_window_scale_ = qreal(my_window_dpi_) / 96.0;
}

/**
 * @brief       根据dpi计算缩放尺寸
 * @param[in]   value     设计时尺寸
 * @return      缩放后尺寸
 */
qreal StyleHelper::dpiScaled(qreal value)
{
#ifdef Q_OS_MAC
  // mac系统dpi一直保持72
  return value;
#else
  return (value * my_window_scale_);
#endif
}

/**
 * @brief       根据dpi缩放控件大小
 * @param[in]   widget    控件
 */
void StyleHelper::sizeScaled(QWidget *widget)
{
#ifdef Q_OS_MAC
  return;
#else
  // 调整布局器的边距
  foreach (QLayout *layout, widget->findChildren<QLayout*>())
  {
    QMargins margins = layout->contentsMargins();
    margins.setBottom(margins.bottom() * my_window_scale_);
    margins.setTop(margins.top() * my_window_scale_);
    margins.setLeft(margins.left() * my_window_scale_);
    margins.setRight(margins.right() * my_window_scale_);
    layout->setContentsMargins(margins);
  
    if (layout->inherits("QGridLayout"))
    {
      QGridLayout *grid_layout = qobject_cast<QGridLayout *>(layout);
      grid_layout->setHorizontalSpacing(grid_layout->horizontalSpacing() * my_window_scale_);
      grid_layout->setVerticalSpacing(grid_layout->verticalSpacing() * my_window_scale_);
    }
    else if (layout->inherits("QFormLayout"))
    {
      QFormLayout *form_layout = qobject_cast<QFormLayout *>(layout);
      form_layout->setHorizontalSpacing(form_layout->horizontalSpacing() * my_window_scale_);
      form_layout->setVerticalSpacing(form_layout->verticalSpacing() * my_window_scale_);
    }
    else
    {
      layout->setSpacing(layout->spacing() * my_window_scale_);
    }
  }
#endif
}

使用api调整widget的尺寸

// 在页面的构造函数中调用
MyDialog::MyDialog(QWidget *parent) :
    QDialog(parent, Qt::MSWindowsFixedSizeDialogHint),
    ui(new Ui::MyDialog)
{
  ui->setupUi(this);
  // 适配分辨率大小
  StyleHelper::sizeScaled(this);
}

// 在一些设置大小的地方使用
ui->tool_button->setIconSize(QSize(StyleHelper::dpiScaled(24), StyleHelper::dpiScaled(24)));

3.3 qss尺寸问题

qss中尺寸使用的px单位,改为em使用。根据实际情况,可以灵活调整,共同使用px和em单位。

/* 对控件进行拉伸,使用了em单位 */
QMenu::item {
    min-width: 6.5em;
    min-height: 1.2em;
    background-color: transparent;
    margin: 0.1em;
    padding: 0em 0.5em 0em 0em;
}

/* 某些地方希望固定尺寸,不进行拉伸,则使用px单位 */
QToolButton {
  border: 1px solid #FFFFFF;
  border-radius: 0px;
  padding: 2px;
}

3.4 结论

以上3种方法组合使用,基本满足了大部分情况,若有哪里没实现到缩放的地方,可按照该思路一步一步解决。
该方案的效果还是比较符合预期,虽然实现起来比较繁琐复杂,所以能够在开发初期考虑到该问题,还是能够比较解决的。文章来源地址https://www.toymoban.com/news/detail-416368.html

到了这里,关于Qt5 高分辨率支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RK3588 配置HDMI支持8K分辨率输出

    RK3588 芯片最高支持的输出分辨率可以到8K,由于Android12 SDK要支持多个显示接口,所以默认最高只配置了4K的分辨率支持,下面以RK3588-EVB1的开发板上配置HDMI输出8K输出为例进行说明如何让RK3588支持8K分辨率。 本文配置RK3588-EVB1开发HDMI0接口输出8K分辨率。 提cru ACLK_VOP的频率到

    2024年02月12日
    浏览(73)
  • Qt怎么获取显示器分辨率

    您可以使用QScreen类来获取当前显示器的分辨率。以下是一个示例代码: 上面的程序将输出主屏幕的分辨率。 如果您有多个显示器并且需要获取其中一个的分辨率,则可以使用QDesktopWidget类。下面是一个示例代码: 上面的程序将输出第2个屏幕的分辨率。请注意,屏幕编号从

    2024年02月13日
    浏览(52)
  • Qt获取屏幕(桌面)的大小或分辨率

    Qt提供QDesktopWidget和QScreen两个类获取屏幕大小。Qt5开始,QDesktopWidget官方不建议使用,改为QScreen。Qt 6.0 及之后版本,QDesktopWidget 已从QtWidgets 模块中被彻底移除。 QDesktopWidget 提供了详细的位置信息,其能够自动返回窗口在用户窗口的位置和应用程序窗口的位置。 如果是多屏幕

    2024年02月07日
    浏览(60)
  • 【QT】如何获取屏幕(桌面)的大小或分辨率

    QDesktopWidget 提供了详细的位置信息,其能够自动返回窗口在用户窗口的位置和应用程序窗口的位置 Qt5开始,QDesktopWidget官方不建议使用,改为QScreen。 Qt 6.0 及之后版本,QDesktopWidget 已从QtWidgets 模块中被彻底移除。 Qt5开始,QDesktopWidget官方不建议使用,改为QScreen。 注意:如果

    2024年02月11日
    浏览(45)
  • QT实现窗口大小随分辨率变化而变化

    先上三张效果图,分别是原窗口、等比放大窗口和等比缩小窗口。 实现原理,就是借用QGraphicsView的缩放功能来实现的,并且做好QGraphicsView的防锯齿设置,就能完美的适应各种不同分辨率的显示器上了。 分辨率转换原理,如果窗口需要放在大分辨率的显示器上,需要将原窗口

    2024年02月12日
    浏览(44)
  • 【MATLAB】Linux版本 高分辨率屏 调整显示缩放

    安装了linux版本的MATLAB R2023b之后,发现工具栏字体很小不方便使用,所以上网找到了MATLAB论坛上某位大佬的教程:参考链接,放在这里供各位参考 。 这里注明我的matlab安装环境仅供参考,未在其他环境下测试过,有效性未知: Ubuntu 20.04 MATLAB R2023b 在MATLAB命令行中输入下面

    2024年01月16日
    浏览(83)
  • 关于Qt适配不同分辨率和缩放率时可能遇到的问题和解决方案

    如果没有特殊的处理,Qt的UI窗口在不同的分辨率和缩放率下,其显示效果可能会出现问题,常见的有: 子控件堆叠,无法显示完整 窗口尺寸变大,超出屏幕的显示范围 控件变形,长宽比不合理 界面模糊 字体变大,控件尺寸却没有变化 有两种方式可以对UI界面进行良好的缩

    2024年02月05日
    浏览(51)
  • FPGA纯verilog代码实现H265视频压缩 支持4K30帧分辨率 提供工程源码和技术支持

    H265视频压缩与解码在FPGA图传领域应用广泛,Xilinx高端器件已经内嵌了H265加速器,在Linux系统下调用API即可使用,但对于需要定制私有算法或者协议的H264视频压缩与解码应用或者学习研究者而言,纯verilog代码实现H264视频压缩依然具有实用价值,本设计采用纯verilog代码实现

    2024年02月07日
    浏览(55)
  • FPGA基于VDMA实现任意分辨率视频输出显示,高度贴近真实项目,提供工程源码和技术支持

    之前写过一篇FPGA纯verilog实现任意分辨率视频输出显示,高度贴近真实项目,提供工程源码和技术支持的文章,讲述了基于AXI协议的FDMA实现任意分辨率视频输出显示,但对于习惯使用zynq或者Microblaze的兄弟来说,更喜欢用VDMA,本设计就是基于VDMA实现任意分辨率视频输出显示,

    2024年02月12日
    浏览(45)
  • FPGA解码MIPI视频 OV5647 2line CSI2 720P分辨率采集 提供工程源码和技术支持

    FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了,MIPI解码难度之高,令无数英雄竞折腰,以至于Xilinx官方不得不推出专用的IP核供开发者使用,不然太高端的操作直接吓退一大批FPGA开发者,就没人玩儿了。 本设计基于Xilinx的Kintex7开发板,采集OV5647 摄像

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包