如何避免在PyQt中DPI缩放导致QIcon模糊的问题?

2026-05-25 17:361阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计678个文字,预计阅读时间需要3分钟。

如何避免在PyQt中DPI缩放导致QIcon模糊的问题?

问题描述:描述如下显示器分辨率下的分析率越来越高,如果不启用DPI缩放,软件的文字和图标在高清屏下会显得非常小,看起来非常费眼。从5.6版本开始,Qt支持DPI缩放功能,Qt6开始,这个功能得到了增强。

分析结果:随着分辨率的提高,如果未启用DPI缩放,Qt软件在高清屏幕上的文字和图标会显得过于细小,影响视觉效果。自5.6版本起,Qt已支持DPI缩放功能,而在Qt6版本中,这一功能得到了进一步优化。

问题描述

如今显示器的分辨率越来越高,如果不启用 DPI 缩放,软件的字体和图标在高分屏下就会显得非常小,看得很累人。从 5.6 版本开始,Qt 便能支持 DPI 缩放功能,Qt6 开始这个功能是默认开启的。

启用 DPI 缩放后,文字不会有太明显的锯齿问题,但是使用 QIcon 设置的图标却会显得很模糊。比如下述代码:

# coding:utf-8 import os import sys from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication, QPushButton, QWidget class Demo(QWidget): def __init__(self): super().__init__(parent=None) self.resize(300, 300) self.button = QPushButton(' Shuffle all', self) self.button.setIcon(QIcon("Shuffle.png")) self.button.move(self.width()//2-self.button.width()//2, self.height()//2-self.button.height()//2) if __name__ == '__main__': os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" os.environ["QT_SCALE_FACTOR"] = '1.25' app = QApplication(sys.argv) demo = Demo() demo.show() app.exec_()

运行结果如下图所示,可以看到图标的锯齿现象非常明显:

问题解决

QIcon 底层依靠 QIconEngine 来绘制图标,生成图标的 pixmap。猜测 QIconEngine 使用 QPainter 绘制图标时没有设置 QPainter.SmoothPixmapTransform 标志位,所以导致只缩放了图标,而没有进行平滑插值。为了解决这个问题,我们可以继承 QIconEngine,重写两个虚方法 paint()pixmap(),代码如下:

如何避免在PyQt中DPI缩放导致QIcon模糊的问题?

# coding:utf-8 from PyQt5.QtCore import QPoint, QRect, QSize, Qt from PyQt5.QtGui import QIcon, QIconEngine, QImage, QPixmap, QPainter class PixmapIconEngine(QIconEngine): """ Pixmap icon engine """ def __init__(self, iconPath: str): self.iconPath = iconPath super().__init__() def paint(self, painter: QPainter, rect: QRect, mode: QIcon.Mode, state: QIcon.State): painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) painter.drawImage(rect, QImage(self.iconPath)) def pixmap(self, size: QSize, mode: QIcon.Mode, state: QIcon.State) -> QPixmap: pixmap = QPixmap(size) pixmap.fill(Qt.transparent) self.paint(QPainter(pixmap), QRect(QPoint(0, 0), size), mode, state) return pixmap class Icon(QIcon): def __init__(self, iconPath: str): self.iconPath = iconPath super().__init__(PixmapIconEngine(iconPath))

接着只要把 QIcon 换成 Icon,并开启 app.setAttribute(Qt.AA_UseHighDpiPixmaps),就能解决图标模糊的问题了,效果如下图所示:

本文共计678个文字,预计阅读时间需要3分钟。

如何避免在PyQt中DPI缩放导致QIcon模糊的问题?

问题描述:描述如下显示器分辨率下的分析率越来越高,如果不启用DPI缩放,软件的文字和图标在高清屏下会显得非常小,看起来非常费眼。从5.6版本开始,Qt支持DPI缩放功能,Qt6开始,这个功能得到了增强。

分析结果:随着分辨率的提高,如果未启用DPI缩放,Qt软件在高清屏幕上的文字和图标会显得过于细小,影响视觉效果。自5.6版本起,Qt已支持DPI缩放功能,而在Qt6版本中,这一功能得到了进一步优化。

问题描述

如今显示器的分辨率越来越高,如果不启用 DPI 缩放,软件的字体和图标在高分屏下就会显得非常小,看得很累人。从 5.6 版本开始,Qt 便能支持 DPI 缩放功能,Qt6 开始这个功能是默认开启的。

启用 DPI 缩放后,文字不会有太明显的锯齿问题,但是使用 QIcon 设置的图标却会显得很模糊。比如下述代码:

# coding:utf-8 import os import sys from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication, QPushButton, QWidget class Demo(QWidget): def __init__(self): super().__init__(parent=None) self.resize(300, 300) self.button = QPushButton(' Shuffle all', self) self.button.setIcon(QIcon("Shuffle.png")) self.button.move(self.width()//2-self.button.width()//2, self.height()//2-self.button.height()//2) if __name__ == '__main__': os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" os.environ["QT_SCALE_FACTOR"] = '1.25' app = QApplication(sys.argv) demo = Demo() demo.show() app.exec_()

运行结果如下图所示,可以看到图标的锯齿现象非常明显:

问题解决

QIcon 底层依靠 QIconEngine 来绘制图标,生成图标的 pixmap。猜测 QIconEngine 使用 QPainter 绘制图标时没有设置 QPainter.SmoothPixmapTransform 标志位,所以导致只缩放了图标,而没有进行平滑插值。为了解决这个问题,我们可以继承 QIconEngine,重写两个虚方法 paint()pixmap(),代码如下:

如何避免在PyQt中DPI缩放导致QIcon模糊的问题?

# coding:utf-8 from PyQt5.QtCore import QPoint, QRect, QSize, Qt from PyQt5.QtGui import QIcon, QIconEngine, QImage, QPixmap, QPainter class PixmapIconEngine(QIconEngine): """ Pixmap icon engine """ def __init__(self, iconPath: str): self.iconPath = iconPath super().__init__() def paint(self, painter: QPainter, rect: QRect, mode: QIcon.Mode, state: QIcon.State): painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) painter.drawImage(rect, QImage(self.iconPath)) def pixmap(self, size: QSize, mode: QIcon.Mode, state: QIcon.State) -> QPixmap: pixmap = QPixmap(size) pixmap.fill(Qt.transparent) self.paint(QPainter(pixmap), QRect(QPoint(0, 0), size), mode, state) return pixmap class Icon(QIcon): def __init__(self, iconPath: str): self.iconPath = iconPath super().__init__(PixmapIconEngine(iconPath))

接着只要把 QIcon 换成 Icon,并开启 app.setAttribute(Qt.AA_UseHighDpiPixmaps),就能解决图标模糊的问题了,效果如下图所示: