python 系统托盘_使用 PySide 实现 Python 系统托盘图示
系统托盘图示 (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 系统托盘图示相关推荐
- 查看Python的版本_查看当前安装Python的版本
一.查看Python的版本_查看当前安装Python的版本 具体方法: 首先按[win+r]组合键打开运行: 然后输入cmd,点击[确定]: 最后执行[python --version]命令即可. 特 ...
- python编程基础_月隐学python第2课
python编程基础_月隐学python第2课 学习目标 掌握变量的输入和输出 掌握数据类型的基本概念 掌握算数运算 1.变量的输入和输出 1.1 变量输入 使用input输入 input用于输入数据 ...
- 积分商城系统开发_专业提供积分商城系统定制解决方案
积分商城系统开发_专业提供积分商城系统定制解决方案 一.什么是积分商城? 1.积分商城的第一种理解,偏重于"积分".即积分商城是专门为消化"积分"这一奖励而特设 ...
- python iot 开源_开源IOT 最小物联网系统
文档 一步步搭建物联网系统 HTTP vs CoAP 现有的这个版本是HTTP版,目前的CoAP版正在开发中,欢迎加入. https://github.com/phodal/iot-coap Mini ...
- python并行运算库_最佳并行绘图Python库简介:“ HiPlot”
python并行运算库 HiPlot is Facebook's Python library to support visualization of high-dimensional data ta ...
- python内存泄漏_诊断和修复Python中的内存泄漏
python内存泄漏 Fugue uses Python extensively throughout the Conductor and in our support tools, due to i ...
- 如何提高python的运行效率_几个提升Python运行效率的方法之间的对比
在我看来,python社区分为了三个流派,分别是python 2.x组织,3.x组织和PyPy组织.这个分类基本上可以归根于类库的兼容性和速度.这篇文章将聚焦于一些通用代码的优化技巧以及编译成C后性能 ...
- sublime搭建python开发环境_使用sublime搭建python开发环境
sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等.还可自定义键绑定,菜单和工具栏.Sublime Text的主要功能包括:拼写检查,书签,完整的 P ...
- python opencv手册_教你用Python实现5毛钱特效(给你的视频来点料)
一.前言 请务必看到最后.Python牛已经不是一天两天的事了,但是我开始也没想到,Python能这么牛.前段时间接触了一个批量抠图的模型库,而后在一些视频中找到灵感,觉得应该可以通过抠图的方式,给视 ...
最新文章
- 100法拉电容生猛无线充电背后原因
- linux下shell编程
- 超级计算机预测降雪,南方九省即将大雪纷飞?超级计算机:可能性增加,但还没有确定...
- 信息系统项目管理师-计算题专题(一)进度类计算
- 磁盘与文件系统管理( 认识磁盘,了解磁盘,文件系统的建立与自动挂载)
- *** error 65: access violation at C:0x001B : no 'execute/read' permission
- weka软件使用问题解决(一)
- php获取扫码枪的内容,C#_C#实现简单获取扫码枪信息代码,一个扫码枪遵循TCP协议,通过 - phpStudy...
- android知乎多图片选择,知乎开源Matisse图片选择器使用
- windows用ffmpeg将flv视频转换为mp4
- 基于Selenium和ChromeDriver的自动化页面性能测试
- 计算机运维方向要考什么证,IT运维项目经理考的证
- acm暑期集训_2020.07.02
- 文本与字体样式3.0
- 双硬盘多系统独立引导(2-Windows xp Win7)
- PW4053,USB C口5V输入,三节串联锂电池充电IC,12.6V1A充电板
- alias,unalias命令
- GDOI2020退役记
- IBM小型机AIX操作系统总结02--软件安装
- Android APK文件结构 完整打包编译的流程 APK安装过程 详解
热门文章
- Mysql 死锁过程及案例详解之用户自定义锁
- 窗口分析函数_9_计算组内总和的占比
- html语言中括号怎么打,HTML语言中括号(尖括号)的字符编码
- verilog 移位运算符 说明_FPGA、数字IC系列(2)——电子科大与北航部分Verilog题目与解析...
- matlab中uint16(uint8)函数的用法
- map传参上下文赋值的问题
- 信息安全系统设计基础实验四:外设驱动程序设计 20145222黄亚奇 20145213祁玮
- GLSL三种修饰符区别与用途(uniform,attribute和varying)
- Windows操作系统启动介绍(二)
- 白话设计模式——Builder