如何在PyQt5应用中覆盖系统执行的DPI缩放
解决Qt应用覆盖系统DPI缩放的问题
一、确保Qt属性设置的正确时机
Qt.AA_DisableHighDpiScaling必须在任何Qt对象实例化前设置,包括QGuiApplication或QApplication。顺序错误会导致属性完全不生效,示例代码:
import sys from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5.QtCore import Qt # 先设置属性,再创建应用实例 QApplication.setAttribute(Qt.AA_DisableHighDpiScaling) app = QApplication(sys.argv) window = QMainWindow() window.show() sys.exit(app.exec_())
二、正确配置Windows DPI感知等级
你使用的SetProcessDpiAwareness(1)是系统DPI感知,会跟随系统全局缩放比例。如果要完全脱离系统缩放控制,需要调整感知等级并结合Qt的对应设置:
方式1:完全禁用所有缩放(按原始像素渲染)
import ctypes from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication # 设置Windows DPI感知为"不感知"(等级0),阻止系统对进程缩放 ctypes.windll.shcore.SetProcessDpiAwareness(0) # 禁用Qt自身的高DPI缩放逻辑 QApplication.setAttribute(Qt.AA_DisableHighDpiScaling) app = QApplication([]) # 后续窗口代码...
方式2:自定义缩放比例(替代系统缩放)
如果需要手动控制缩放比例而非完全禁用,可启用Qt的高DPI支持后手动指定缩放因子:
import ctypes from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication # 设置Windows为每显示器DPI感知(等级2),让Qt能获取真实显示器DPI ctypes.windll.shcore.SetProcessDpiAwareness(2) # 启用Qt高DPI缩放基础支持 QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # 关闭Qt自动缩放,改为手动控制 QApplication.setAttribute(Qt.AA_DisableHighDpiScaling, False) app = QApplication([]) # 强制设置缩放因子为1.0(即无缩放),也可根据需求改为其他值 app.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app.setScaleFactor(1.0) # 后续窗口代码...
三、检查应用程序清单文件
如果你的程序附带app.manifest文件,其中的<dpiAware>或<dpiAwareness>配置会优先于代码设置生效。确保清单中没有以下冲突配置,或直接删除该文件:
<!-- 若存在此节点,会覆盖代码中的DPI设置 --> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware>true/PM</dpiAware> </windowsSettings> </application>
四、验证设置是否生效
可通过以下代码检查当前DPI状态和缩放因子,确认设置是否生效:
# 检查Windows DPI感知等级 awareness = ctypes.c_int() ctypes.windll.shcore.GetProcessDpiAwareness(0, ctypes.byref(awareness)) print(f"Windows DPI感知等级: {awareness.value}") # 检查Qt缩放因子 print(f"Qt缩放因子: {app.devicePixelRatio()}")
内容的提问来源于stack exchange,提问作者NightrollCodez
相关产品推荐
相关产品推荐

