Skip to main content

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.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crosstray-0.1.1.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crosstray-0.1.1-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file crosstray-0.1.1.tar.gz.

File metadata

  • Download URL: crosstray-0.1.1.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for crosstray-0.1.1.tar.gz
Algorithm Hash digest
SHA256 52f20acf83534907aebaf6fb3fa78a66e35ab35584411bb6c5c398e9c1944638
MD5 6d6a431d5846ba40757641dcde78ff6d
BLAKE2b-256 0979f887ec7a8bdbefb23d3e04fcb71fdc169f1ab52587e2b119ef256f349d4e

See more details on using hashes here.

File details

Details for the file crosstray-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: crosstray-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for crosstray-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71246a63bca4e5b0fad445b563bff14e5ccff56b26b9bf496a28f1b3458c4c84
MD5 cf55f6dde5967d543a7ffa46737712c3
BLAKE2b-256 bc16cacab56059ed7f7d148b877205c60c623e7a06660da580ecc24ef3b6415c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page