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

PyQt5托盘图标本地Mac正常显示,客户端Mac无法显示求助

PyQt5系统托盘图标在部分Mac设备不显示的排查方案

我开发了一个PyQt5应用,用于显示系统托盘图标。该图标在我的Mac设备上可正常显示,但在客户端的Mac设备上无法显示(暂无截图)。最初猜测是客户端的托盘图标数量达到上限,但移除一个图标后重新运行应用,问题仍未解决。相关代码如下:

import logging
import signal
import sys
import subprocess
import os

from PyQt5 import QtGui, QtWidgets, QtCore

logger = logging.getLogger(__name__)


# This is't used...
def refresh(*args):
    logger.warning('Hello')


class Application(QtWidgets.QApplication):
    def event(self, e):
        return QtWidgets.QApplication.event(self, e)


class Application(QtWidgets.QApplication):
    def launch_terminal(self):
        # start backup script
        cmd = f"cd {os.getcwd()}; env -i PATH=$PATH bash -c ./backup.sh"
        subprocess.run(['osascript', '-e', f'tell application "Terminal" to do script "{cmd}"'])

        def check_backup():
            if os.path.exists('/tmp/backup_done'):
                os.remove('/tmp/backup_done')
                self.quit()

        # start timer to check if backup is completed
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(check_backup)
        self.timer.start(1000)  # check every second


class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.menu = QtWidgets.QMenu(parent)
        self.refresh_action = self.menu.addAction("Refresh")
        self.refresh_action.triggered.connect(refresh)

        self.exit_action = self.menu.addAction("Exit")
        self.exit_action.triggered.connect(QtWidgets.qApp.quit)

        self.setContextMenu(self.menu)

        # Create a pixmap from a Unicode character
        font = QtGui.QFont("Arial", 30)
        pixmap = QtGui.QPixmap(50, 50)
        pixmap.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(pixmap)
        painter.setFont(font)
        painter.drawText(pixmap.rect(), QtCore.Qt.AlignCenter, "🔴")
        painter.end()

        self.setIcon(QtGui.QIcon(pixmap))


def main():
    app = Application(sys.argv)

    # Registers a signal handler to exit the application gracefully
    # when receiving a SIGINT signal (e.g., Ctrl+C on the terminal). 
    signal.signal(signal.SIGINT, lambda *a: app.quit())

    tray_icon = SystemTrayIcon()
    tray_icon.exit_action.triggered.connect(app.quit)

    tray_icon.show()

    # Timer calls Application.event repeatedly.
    app.startTimer(200)

    app.launch_terminal()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

可能的原因及解决办法

1. 字体缺失或Unicode渲染兼容性问题

代码中使用Arial字体绘制Unicode emoji图标(🔴),如果客户端Mac未安装Arial字体,或者系统对emoji的渲染机制存在差异,会导致图标无法生成显示。

  • 改用系统默认支持的字体,比如Helvetica,或者直接省略字体参数让系统自动适配:font = QtGui.QFont()
  • 替换为本地图片文件作为托盘图标,避免动态绘制的兼容性问题:self.setIcon(QtGui.QIcon("icon.png"))(提前准备好png格式的图标文件)

2. 重复定义Application类导致异常

代码中重复定义了Application类,第一个类仅重写event方法但未被实际使用,这种重复定义可能在不同环境下引发初始化异常。建议合并类的功能:

class Application(QtWidgets.QApplication):
    def event(self, e):
        return QtWidgets.QApplication.event(self, e)

    def launch_terminal(self):
        # start backup script
        cmd = f"cd {os.getcwd()}; env -i PATH=$PATH bash -c ./backup.sh"
        subprocess.run(['osascript', '-e', f'tell application "Terminal" to do script "{cmd}"'])

        def check_backup():
            if os.path.exists('/tmp/backup_done'):
                os.remove('/tmp/backup_done')
                self.quit()

        # start timer to check if backup is completed
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(check_backup)
        self.timer.start(1000)  # check every second

3. Mac系统权限或设置限制

  • 检查客户端Mac的系统设置:打开「系统设置」→「通知」,找到该应用并确认允许通知(托盘图标显示可能依赖通知权限)
  • 确认托盘图标是否被隐藏:Ventura及以上版本的MacOS会将部分托盘图标收纳到菜单栏右侧的「更多图标」中(点击箭头展开查看)
  • 排查是否有安全软件拦截了应用的托盘显示权限

4. 冗余定时器干扰事件循环

代码中调用app.startTimer(200)反复触发event方法,但app.exec_()本身已处理事件循环,该冗余定时器可能干扰托盘图标的初始化流程,建议移除该代码。

5. 动态Pixmap绘制的兼容性问题

动态绘制透明背景的Pixmap可能在部分设备上渲染异常,可以临时修改背景色测试:

pixmap = QtGui.QPixmap(50, 50)
pixmap.fill(QtCore.Qt.white)  # 替换透明背景为白色测试是否能显示

内容的提问来源于stack exchange,提问作者P i

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:05:15