问题描述

如今显示器的分辨率越来越高,如果不启用 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(),代码如下:

# 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),就能解决图标模糊的问题了,效果如下图所示:

如何在 pyqt 中解决启用 DPI 缩放后 QIcon 模糊的问题的更多相关文章

  1. 如何在 pyqt 中解决国际化 tr() 函数不起作用的问题

    前言 有些时候我们在父类中使用了 self.tr('XXX'),使用 Qt Linguist 完成翻译并导出 qm 文件后,发现子类中仍然是英文原文.比如下面这段代码: class AlbumCard ...

  2. 如何在pyqt中自定义无边框窗口

    前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...

  3. 如何在pyqt中给无边框窗口添加DWM环绕阴影

    前言 在之前的博客<如何在pyqt中通过调用SetWindowCompositionAttribute实现Win10亚克力效果>中,我们实现了窗口的亚克力效果,同时也用SetWindowC ...

  4. 如何在pyqt中通过调用 SetWindowCompositionAttribute 实现Win10亚克力效果

    亚克力效果 在<如何在pyqt中实现窗口磨砂效果>和<如何在pyqt中实现win10亚克力效果>中,我们调用C++ dll来实现窗口效果,这种方法要求电脑上必须装有MSVC.V ...

  5. 如何在pyqt中在实现无边框窗口的同时保留Windows窗口动画效果(一)

    无边框窗体的实现思路 在pyqt中只要 self.setWindowFlags(Qt.FramelessWindowHint) 就可以实现边框的去除,但是没了标题栏也意味着窗口大小无法改变.窗口无法拖 ...

  6. 如何在 pyqt 中捕获并处理 Alt+F4 快捷键

    前言 如果在 Windows 系统的任意一个窗口中按下 Alt+F4,默认行为是关闭窗口(或者最小化到托盘).对于使用了亚克力效果的窗口,使用 Alt+F4 最小化到托盘,再次弹出窗口的时候可能出现亚 ...

  7. 如何在pyqt中实现窗口磨砂效果

    磨砂效果的实现思路 这两周一直在思考怎么在pyqt上实现窗口磨砂效果,网上搜了一圈,全都是 C++ 的实现方法.正好今天查python的官方文档的时候看到了 ctypes 里面的 HWND,想想倒不如 ...

  8. 如何在pyqt中实现win10亚克力效果

    亚克力效果的实现思路 上一篇博客<如何在pyqt中实现窗口磨砂效果> 中实现了win7中的Aero效果,但是和win10的亚克力效果相比,Aero还是差了点内味.所以今天早上又在网上搜了一 ...

  9. 如何在pyqt中实现带动画的动态QMenu

    弹出菜单的视觉效果 QLineEdit 原生的菜单弹出效果十分生硬,而且样式很丑.所以照着Groove中单行输入框弹出菜单的样式和动画效果写了一个可以实现动态变化Item的弹出菜单,根据剪贴板的内容是 ...

随机推荐

  1. Citus 分布式 PostgreSQL 集群 - SQL Reference(手动查询传播)

    手动查询传播 当用户发出查询时,Citus coordinator 将其划分为更小的查询片段,其中每个查询片段可以在工作分片上独立运行.这允许 Citus 将每个查询分布在集群中. 但是,将查询划分为 ...

  2. MOS管工作原理精讲

  3. EMC EMI EMS定义与区别

    一.EMC EMI EMS定义: EMC(ElectromagneticCompatibility) 电磁兼容,是指设备或系统在电磁环境中性能不降级的状态.电磁兼容,一方面要求系统内没有严重的干扰源, ...

  4. Graphics 与 DisplayObject 的关系

    在原生 Canvas 中,其实并没有 DisplayObject 的概念,它只有绘制图像的概念. 大部分的原生绘制图形或图像的 API 一般是这样的: api(x, y, ...) 例如 rect 就 ...

  5. web项目中视频的上传和展示

    思路: 上传:<form>表单提交视频-->后台使用字节流保存到本地. 展示:<video>标签展示: src属性发送请求 --> 使用字节流将视频绑定到响应并返回 ...

  6. 【weex开发】weex官方源码

    公司目前使用版本:weex_sdk:0.10.0 介绍地址:https://bintray.com/alibabaweex/maven/weex_sdk/0.18.0 weex最新版本:weex_sd ...

  7. js知识梳理3:创建对象的模式探究

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  8. Servlet实现登录注册

    1.注册页面register.html <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  9. [资源] 桃宝上十几块买的C#教程网盘

    我粗略的看了下觉得挺好的,分享给大家 链接:https://pan.baidu.com/s/1iHuLUXde4_L7NB-Zw9JWNg 提取码:1314

  10. Redux基础必知必会 reducer拆分 中间件 单向数据流

    什么是 redux? 三大原则? 什么是 redux Redux 是一个基于 js 的全局可预测状态容器,主要用于现代前端框架中进行全局状态管理,能够在不同组件之间进行状态共享 Redux 常与 Re ...