You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从系统终端运行时QSystemTrayIcon设置的尺寸未生效但VSCode终端正常

根因分析
  • 终端环境变量差异:VSCode内嵌终端启动时会自动注入Qt高分屏适配相关的环境变量,原生Bash终端默认无此类变量,导致Qt的缩放逻辑执行结果不一致。
  • 代码未适配多缩放场景:创建QPixmap时硬编码像素尺寸,未结合当前屏幕的设备像素比动态调整,也未固定文本渲染的字体参数,不同缩放比例下文本显示尺寸会出现偏差。
  • 属性生效兼容性问题:部分PyQt5版本中,通过类方法提前设置应用属性存在不生效的概率,需配合环境变量强制指定适配规则。
修复方案
  1. 代码入口处强制设置Qt高分屏适配环境变量,屏蔽不同终端的环境差异
  2. 生成图标前获取当前屏幕的设备像素比,动态计算Pixmap的物理像素尺寸
  3. 主动固定绘图字体大小,保证文本渲染尺寸一致
  4. 为Pixmap设置对应设备像素比,让Qt自动适配托盘图标显示要求
修复后完整代码
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtWidgets, QtGui, QtSvg

# 强制配置Qt高分屏适配环境变量,屏蔽终端环境差异
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
os.environ["QT_SCREEN_SCALE_FACTORS"] = ""
os.environ["QT_SCALE_FACTOR"] = ""

def create_tray_icon(label):
    r"""Creates QIcon with the given label."""
    # 托盘图标逻辑尺寸,可根据需求调整
    logic_w, logic_h = 88, 22
    # 获取当前屏幕设备像素比
    screen = QApplication.primaryScreen()
    dpr = screen.devicePixelRatio()
    # 计算适配高分屏的物理像素尺寸
    pix_w, pix_h = int(logic_w * dpr), int(logic_h * dpr)
    pixmap = QtGui.QPixmap(pix_w, pix_h)
    pixmap.setDevicePixelRatio(dpr)
    pixmap.fill(QtCore.Qt.transparent)
    
    painter = QtGui.QPainter(pixmap)
    # 固定字体尺寸,避免系统默认字体差异影响显示效果
    font = painter.font()
    font.setPixelSize(int(14 * dpr))
    painter.setFont(font)
    
    painter.setPen(QtGui.QColor("white"))
    align = int(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
    painter.drawText(pixmap.rect(), align, str(label))
    painter.end()
    icon = QtGui.QIcon()
    icon.addPixmap(pixmap)
    return icon


class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
        self.menu = QtWidgets.QMenu(parent)
        exitAction = self.menu.addAction("Exit")
        exitAction.triggered.connect(lambda: sys.exit())
        self.setContextMenu(self.menu)


def memprofilerApp():
    r"""Runs the Qt Application."""
    QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
    app = QApplication(sys.argv)
    icon = create_tray_icon(label="Hello world!")
    trayIcon = SystemTrayIcon(icon)
    trayIcon.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    memprofilerApp()

内容的提问来源于stack exchange,提问作者Blademaster。

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:06:05