系统托盘图示 (system tray icon) 通常用来在桌面应用程序最小化后,不希望在任务列(task

bar)出现时,提供一个简单跟使用者交互的接口。 透过这样的用户接口,应用程序可以在有重要事件发生时,即时通知用户。因此,系统托盘图示常被诸如“邮件检查”、“股票报价”等不需要复杂接口的桌面应用所使用。本文山姆锅说明 Python 如何使用 PySide 来实现一个跨平台 (cross-platform) 的系统托盘图示应用程序。

目前三种主要的桌面操作系统,也就是 Windows, Mac OSX, 以及 Linux,都有支持托盘图示接口,但是名称跟支持程度稍有不同。 PySide (QT) 提供一个跨平台的方案,对大部分的 Python

桌面应用来说,这是适合的方案。如果真的不需要其他接口组件, 可以针对各个平台分别来实现系统托盘程序,对于这样的情况,山姆锅建议使用下列组合:

Windows: PyWin32

Ubuntu(Linux): PyGObject

注意:其中 PyGObject 只适合 GTK3 桌面环境。

执行环境

山姆锅假设以下的执行环境:

Python 2.7.x

PySide 1.2.2

QT 4

范例程序

本文使用 PySide 完成一个单纯的桌面程序 AvaShell,可以做到下列功能:

在系统托盘显示一个图示。

用户点选图示后,会弹跳 (pop-up) 一个菜单。

用户可以从菜单选择离开程序。

是的,目前就只能完成上述功能。

为了封装代码, 先定义一个 Shell 抽象类作为后续实现的基础,这样以后可以依照不同环境选用不同实现:

shell_base.pyview raw1

2

3

4

5

6

7

8

9

10

11

12

13from __future__ import absolute_import, division, print_function, unicode_literals

from abc import abstractmethod

class (object):

def (self):

"""Starts up the shell.

"""

pass

抽象方法(method) run 必须由继承的子类来实现。底下是采用 PySide 的实现类:

shell_pyside.pyview raw1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81from __future__ import absolute_import, print_function, unicode_literals

import sys

import logging

from PySide.QtGui import *

from avashell.shell_base import ShellBase

from avashell.utils import resource_path

_logger = logging.getLogger(__name__)

class MainWnd(QMainWindow):

def __init__(self, shell, icon):

super(MainWnd, self).__init__()

self._shell = shell

self.icon = icon

self.context_menu = None

self.tray_icon = None

if not QSystemTrayIcon.isSystemTrayAvailable():

msg = "I couldn't detect any system tray on this system."

_logger.error(msg)

QMessageBox.critical(None, "AvaShell", msg)

sys.exit(1)

self.init_ui()

def init_ui(self):

self.setWindowIcon(self.icon)

self.setWindowTitle('AvaShell')

self.create_tray_icon(self.icon)

self.tray_icon.show()

def on_tray_activated(self, reason=None):

_logger.debug("Tray icon activated.")

def on_quit(self):

self._shell.quit_app()

def create_context_menu(self):

self.quit_action = QAction("&Quit AvaShell", self, triggered=self.on_quit)

menu = QMenu(self)

menu.addAction(self.quit_action)

return menu

def create_tray_icon(self, icon):

self.context_menu = self.create_context_menu()

self.tray_icon = QSystemTrayIcon(self)

self.tray_icon.setContextMenu(self.context_menu)

self.tray_icon.setIcon(icon)

self.tray_icon.activated.connect(self.on_tray_activated)

class Shell(ShellBase):

""" Shell implementation using PySide

"""

def __init__(self):

super(Shell, self).__init__()

self.app = QApplication(sys.argv)

self.app.setQuitOnLastWindowClosed(False)

self.icon = QIcon(resource_path('res/icon.png'))

self.menu = None

self.wnd = MainWnd(self, self.icon)

def quit_app(self):

self.app.quit()

def run(self):

_logger.info("Shell is running...")

self.app.exec_()

if __name__ == '__main__':

shell = Shell()

shell.run()

Shell 为 ShellBase 的子类,负责建构 QApplication 以及主窗口(MainWnd); 主窗口负责建立 QSystemTrayIcon 这个代表系统托盘的对象,以及它使用的弹出式菜单,同时注册相关事件处理器。由于主窗口并不显示,且不希望主窗口被关闭的时候, 程序自动离开,标号 1 的叙述就是通知 PySide 不要自动离开程序。

为了找到图档资源(resource),另外定义了一个公用函数 resource_path,以便之后在使用 PyInstaller 打包后能正常运行。此公用函数定义在 utils.py 这个文件中。

utils.pyview raw1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18from __future__ import absolute_import, division, print_function, unicode_literals

import os

import sys

def resource_path(relative):

"""Gets the resource's absolute path.

:param relative: the relative path to the resource file.

:return: the absolute path to the resource file.

"""

if hasattr(sys, "_MEIPASS"): # 1

return os.path.join(sys._MEIPASS, relative)

abspath = os.path.abspath(os.path.join(__file__, "..")) # 2

abspath = os.path.dirname(abspath)

return os.path.join(abspath, relative)

标号 1 的叙述判断是否在经过 PyInstaller 打包好的环境执行,如果是则直接使用 sys._MEIPASS 这个特殊属性值作为资源路径; 如果不是, resource_path 则假设资源文件放在它的上层目录。 因此,标号 2 的叙述需要根据 utils.py 与资源的相对位置作调整。

参考数据

结语

使用 PySide 或者 PyQT 可以很方便地实现跨平台的图形接口,对于大部分的桌面应用来说,这是好事。但是对于只需要一个简单的系统托盘图示的应用来说,使用 PySide 意味着额外需要十几 MB 的空间来散布所开发的应用程序。 即使如此,相对于针对各个平台开发所需的时间来说,使用 PySide 通常是比较合理的作法。

python 系统托盘_使用 PySide 实现 Python 系统托盘图示相关推荐

  1. 查看Python的版本_查看当前安装Python的版本

    一.查看Python的版本_查看当前安装Python的版本 具体方法: 首先按[win+r]组合键打开运行: 然后输入cmd,点击[确定]: 最后执行[python --version]命令即可. 特 ...

  2. python编程基础_月隐学python第2课

    python编程基础_月隐学python第2课 学习目标 掌握变量的输入和输出 掌握数据类型的基本概念 掌握算数运算 1.变量的输入和输出 1.1 变量输入 使用input输入 input用于输入数据 ...

  3. 积分商城系统开发_专业提供积分商城系统定制解决方案

    积分商城系统开发_专业提供积分商城系统定制解决方案 一.什么是积分商城? 1.积分商城的第一种理解,偏重于"积分".即积分商城是专门为消化"积分"这一奖励而特设 ...

  4. python iot 开源_开源IOT 最小物联网系统

    文档 一步步搭建物联网系统 HTTP vs CoAP 现有的这个版本是HTTP版,目前的CoAP版正在开发中,欢迎加入. https://github.com/phodal/iot-coap Mini ...

  5. python并行运算库_最佳并行绘图Python库简介:“ HiPlot”

    python并行运算库 HiPlot is Facebook's Python library to support visualization of high-dimensional data ta ...

  6. python内存泄漏_诊断和修复Python中的内存泄漏

    python内存泄漏 Fugue uses Python extensively throughout the Conductor and in our support tools, due to i ...

  7. 如何提高python的运行效率_几个提升Python运行效率的方法之间的对比

    在我看来,python社区分为了三个流派,分别是python 2.x组织,3.x组织和PyPy组织.这个分类基本上可以归根于类库的兼容性和速度.这篇文章将聚焦于一些通用代码的优化技巧以及编译成C后性能 ...

  8. sublime搭建python开发环境_使用sublime搭建python开发环境

    sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等.还可自定义键绑定,菜单和工具栏.Sublime Text的主要功能包括:拼写检查,书签,完整的 P ...

  9. python opencv手册_教你用Python实现5毛钱特效(给你的视频来点料)

    一.前言 请务必看到最后.Python牛已经不是一天两天的事了,但是我开始也没想到,Python能这么牛.前段时间接触了一个批量抠图的模型库,而后在一些视频中找到灵感,觉得应该可以通过抠图的方式,给视 ...

最新文章

  1. 100法拉电容生猛无线充电背后原因
  2. linux下shell编程
  3. 超级计算机预测降雪,南方九省即将大雪纷飞?超级计算机:可能性增加,但还没有确定...
  4. 信息系统项目管理师-计算题专题(一)进度类计算
  5. 磁盘与文件系统管理( 认识磁盘,了解磁盘,文件系统的建立与自动挂载)
  6. *** error 65: access violation at C:0x001B : no 'execute/read' permission
  7. weka软件使用问题解决(一)
  8. php获取扫码枪的内容,C#_C#实现简单获取扫码枪信息代码,一个扫码枪遵循TCP协议,通过 - phpStudy...
  9. android知乎多图片选择,知乎开源Matisse图片选择器使用
  10. windows用ffmpeg将flv视频转换为mp4
  11. 基于Selenium和ChromeDriver的自动化页面性能测试
  12. 计算机运维方向要考什么证,IT运维项目经理考的证
  13. acm暑期集训_2020.07.02
  14. 文本与字体样式3.0
  15. 双硬盘多系统独立引导(2-Windows xp Win7)
  16. PW4053,USB C口5V输入,三节串联锂电池充电IC,12.6V1A充电板
  17. alias,unalias命令
  18. GDOI2020退役记
  19. IBM小型机AIX操作系统总结02--软件安装
  20. Android APK文件结构 完整打包编译的流程 APK安装过程 详解

热门文章

  1. Mysql 死锁过程及案例详解之用户自定义锁
  2. 窗口分析函数_9_计算组内总和的占比
  3. html语言中括号怎么打,HTML语言中括号(尖括号)的字符编码
  4. verilog 移位运算符 说明_FPGA、数字IC系列(2)——电子科大与北航部分Verilog题目与解析...
  5. matlab中uint16(uint8)函数的用法
  6. map传参上下文赋值的问题
  7. 信息安全系统设计基础实验四:外设驱动程序设计 20145222黄亚奇 20145213祁玮
  8. GLSL三种修饰符区别与用途(uniform,attribute和varying)
  9. Windows操作系统启动介绍(二)
  10. 白话设计模式——Builder