SkillAgentSearch skills...

Crosstray

A lightweight Python library for creating system tray icons on Windows. (Future versions will add macOS and Linux support.) No heavy GUI dependencies—just simple status indicators, notifications, and menus.

Install / Use

/learn @UmanSheikh/Crosstray
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

CrossTray

PyPI version License: MIT Python versions

A lightweight, unified Python library for creating system tray/menu bar icons across Windows, macOS, and Linux. No heavy GUI dependencies—just pure Python simplicity for status indicators, notifications, and menus.

Why CrossTray?

  • Cross-Platform Magic: Handles OS-specific quirks automatically (e.g., Windows notification area, macOS menu bar, Linux systray).
  • Minimal Footprint: Dependency-free core (uses stdlib where possible, optional extras for icons/notifications).
  • Easy API: Object-oriented and chainable, inspired by pathlib for intuitive use.
  • Async-Friendly: Supports asyncio for real-time updates without blocking.

Perfect for building desktop utilities like monitors, trackers, or background apps.

Installation

pip install crosstray

Quick Start

from crosstray import Tray

tray = Tray(icon="path/to/icon.png", title="My App")
tray.add_menu_item("Quit", lambda: tray.quit())
tray.run()

For more examples, see Usage.


Features

  • Create tray icons with custom images or text fallbacks.
  • Build nested menus with callbacks.
  • Show balloon notifications/toasts.
  • Dynamic updates (e.g., change icon or menu on the fly).
  • Event loop integration for async apps.
  • Error handling for unsupported platforms.

Usage

Basic Tray Icon

from crosstray import Tray

def on_click(tray: ct.Tray):
    tray.send_notification("Tray Clicked", "You clicked the tray icon!", icon="file.ico", timeout=9000)

tray = Tray(icon="icon.ico", tooltip="Hello World")
tray.on_click = tray.on_click = lambda: on_click(tray)  # Or use tray.add_action("Click", on_click)
tray.run()  # Blocks until quit

With Menu

from crosstray import Tray, MenuItem

tray = Tray(title="Status Monitor")

menu = tray.menu
menu.add_item(MenuItem("Refresh", lambda: print("Refreshing...")))
menu.add_separator()
submenu = menu.add_submenu("Settings")
submenu.add_item(MenuItem("Option 1", lambda: print("Selected 1")))
menu.add_item(MenuItem("Quit", tray.quit))

tray.run()

Async Example

import asyncio
from crosstray import Tray

async def main():
    tray = Tray(icon="icon.png")
    tray.add_menu_item("Update", lambda: print("Updating"))

    # Simulate real-time update
    async def updater():
        while True:
            tray.tooltip = f"Time: {asyncio.get_event_loop().time()}"
            await asyncio.sleep(1)

    asyncio.create_task(updater())
    await tray.run_async()  # Non-blocking

asyncio.run(main())

Contributing

Contributions welcome! Fork the repo, create a branch, and submit a PR. See CONTRIBUTING.md for guidelines.

License

MIT License. See LICENSE for details.

Built with ❤️ by Uman Sheikh. Inspired by community needs for simpler desktop tools.

Related Skills

View on GitHub
GitHub Stars7
CategoryCustomer
Updated1mo ago
Forks2

Languages

Python

Security Score

90/100

Audited on Mar 4, 2026

No findings