pystray
pystray is a Python library that provides cross-platform system tray icon integration. It allows developers to create a system tray icon, define a title, set an image, and attach a popup menu with various actions. The current stable version is 0.19.5, with releases typically occurring as needed for bug fixes and feature enhancements, rather than on a strict schedule.
Common errors
-
RuntimeWarning: Pillow X.Y.Z does not support Python 3.NN and does not provide prebuilt Windows binaries.
cause The installed version of Pillow is not fully compatible with the current Python version, especially on Windows or very new Python releases.fixUpgrade Pillow to the latest version (`pip install --upgrade Pillow`). If the issue persists with a very new Python version, consider downgrading Python to a version officially supported by the latest Pillow release. -
My pystray icon appears but the menu doesn't show up or doesn't respond on Linux.
cause The current Linux desktop environment or backend might not support menus or requires specific dependencies (e.g., AppIndicator, PyGObject).fixEnsure `PyGObject` is installed, especially for AppIndicator backend (`pip install pygobject`). If using a virtual environment on Linux, additional system packages (like `libcairo-dev`, `libgirepository1.0-dev`) might be needed for PyGObject to build. On Xorg, menu support is limited or non-existent. -
My application freezes when I call `icon.run()` after initializing my Tkinter window.
cause `icon.run()` is a blocking call and competes for the main thread with your GUI framework's event loop.fixRun the `pystray` icon in a separate thread using `icon.run_detached()`. For example: `import threading; threading.Thread(target=icon.run_detached).start()`.
Warnings
- breaking `pystray.Icon.run()` is a blocking call and must be run in the main thread on macOS for the system tray icon to function correctly.
- gotcha Menus are not supported or have limited functionality on certain Linux backends (e.g., Xorg). `Icon.HAS_MENU` can be checked at runtime.
- deprecated Older versions of pystray might have compatibility issues with newer Pillow versions or Python releases, leading to `RuntimeWarning` or unexpected behavior.
- gotcha When integrating `pystray` with other GUI frameworks (like Tkinter or PySimpleGUI), `icon.run()` will block the main loop of the other framework.
Install
-
pip install pystray pillow
Imports
- Icon
import pystray.Icon
from pystray import Icon
- Menu
import pystray.Menu
from pystray import Menu, MenuItem
- Image
import Image
from PIL import Image, ImageDraw
Quickstart
import pystray
from PIL import Image, ImageDraw
import os
def create_image(width, height, color1, color2):
# Generate a simple image for the icon
image = Image.new('RGB', (width, height), color1)
dc = ImageDraw.Draw(image)
dc.rectangle((width // 2, 0, width, height // 2), fill=color2)
dc.rectangle((0, height // 2, width // 2, height), fill=color2)
return image
def quit_action(icon, item):
icon.stop()
def show_message(icon, item):
print("Hello from the tray icon!")
# Create an image for the icon
icon_image = create_image(64, 64, 'black', 'white')
# Define the menu
menu = (
pystray.MenuItem('Say Hello', show_message),
pystray.MenuItem('Quit', quit_action)
)
# Create and run the icon
icon = pystray.Icon('my_app_name', icon_image, 'My Awesome App', menu)
# For simple, blocking execution, use icon.run()
# For integration with other GUI frameworks, consider icon.run_detached() in a separate thread.
# In this example, we'll use run() for simplicity.
print("pystray icon is running. Right-click for menu, or click 'Quit' to exit.")
icon.run()