Python使用pystray库实现托盘图标
   2

pystray是一个简单的、跨平台的,用于创建系统托盘图标的第三方库。
本篇文章主要讲解pystray在win平台下使用,如果有跨平台或兼容性上问题,可以去官方仓库提问。

安装

pip install pystray

基本使用

我们先简单创建一个图片,设置下右键菜单,点击菜单看看效果。

1
2
3
4
5
6
7
8
9
import pystray
from PIL import Image
from pystray import MenuItem

menu = (MenuItem('菜单1', lambda: print("点击了菜单1")), MenuItem('菜单2', lambda: print("点击了菜单2")))
image = Image.open("static/img.png")
icon = pystray.Icon("name", image, "鼠标移动到\n托盘图标上\n展示内容", menu)
icon.run()

托盘图标 托盘图标

菜单和通知使用说明

这里演示了菜单和通知的使用方法。通过设置MenuItem不同属性实现不同功能,设置default=True则点击托盘图标时执行,visible属性设置是否可见,enabled设置菜单是否可用。

icon.notify() 可以发起一个通知消息。效果见下图。

 1
 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
import pystray
from PIL import Image
from pystray import MenuItem


def click_menu(icon, item):
    print("点击了", item)


def on_exit(icon, item):
    icon.stop()


def notify(icon: pystray.Icon):
    icon.notify("我是消息类容", "消息标题")


menu = (MenuItem(text='菜单1', action=click_menu), MenuItem(text='菜单2', action=click_menu),
        MenuItem(text='菜单3', action=click_menu, enabled=False),
        MenuItem(text='发送通知', action=notify),
        MenuItem(text='我是点击图标的菜单', action=click_menu, default=True, visible=False),
        MenuItem(text='退出', action=on_exit),
        )
image = Image.open("static/img.png")
icon = pystray.Icon("name", image, "鼠标移动到\n托盘图标上\n展示内容", menu)
icon.run()

菜单演示和通知 菜单演示和通知

结合tkinter同时展示托盘图标和界面

这里简单演示一下,在tkinter中展示托盘图标。

直接执行icon.run()方法,会发现图标出现了,但是界面不出来,这是因为icon.run()会阻塞进入事件循环,处理办法很简单,开一个线程就行了。

这里需要主要,需要设置daemon=True将线程设置为守护线程,使tkinter进程结束,就关闭托盘图标,防止关不掉图标。

现在我们点关闭按钮,程序直接就被停止了,但要我们要实现点击关闭按钮,并不是真正关闭程序而是最小化,点击托盘图标又可以重新进入程序。主要完成这两步就可以实现了:

  1. 通过注册 win.protocol() 注册 WM_DELETE_WINDOW命令,在回调函数中执行 win.withdraw() 从而实现关闭窗口界面。
  2. 给托盘图标的菜单添加 default=True 这个属性,定义点击托盘图标的默认事件,在回调中调用win.deiconify()就能重新打开窗口。

tkinter结合pystray的演示代码

 1
 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
import threading
from tkinter import Tk

import pystray
from PIL import Image
from pystray import MenuItem, Menu


def quit_window(icon: pystray.Icon):
    icon.stop()
    win.destroy()


def show_window():
    win.deiconify()


def on_exit():
    win.withdraw()


menu = (MenuItem('显示', show_window, default=True), Menu.SEPARATOR, MenuItem('退出', quit_window))
image = Image.open("static/img.png")
icon = pystray.Icon("icon", image, "图标名称", menu)
win = Tk()
win.geometry("500x300")

# 重新定义点击关闭按钮的处理
win.protocol('WM_DELETE_WINDOW', on_exit)

threading.Thread(target=icon.run, daemon=True).start()

win.mainloop()

站长微信
请备注来意
二维码