Hello world

A complete tray application: a window showing Hello World! and a button that fires a notification, with a tray icon and quit-with-confirmation. Almost all of the fiddly parts – the confirmation dialog, the tray menu, hiding to the tray on close, centring, theming, and the notification fallback – are handled by TkApp, so the app itself stays tiny.

import tkinter as tk
from tkinter import ttk

from PIL import Image

from sevaht_gui import TkApp


def render_icon(size: int) -> Image.Image:
    """Draw the tray/window icon (any PIL image, file path, or renderer works)."""
    return Image.new("RGBA", (size, size), (0, 128, 255, 255))


def main() -> None:
    # quit_confirm gives the tray "Quit" item and the window close button a
    # confirmation dialog for free.
    app = TkApp(quit_confirm="Quit Hello World?")
    app.root.title("Hello World")

    content = ttk.Frame(app.root, padding=24)
    content.pack(fill=tk.BOTH, expand=True)
    ttk.Label(content, text="Hello World!").pack(pady=(0, 12))
    ttk.Button(
        content,
        text="Send a notification",
        command=lambda: app.notify("Hello World", "This is a notification."),
    ).pack()

    # None if there is no system tray; the app then runs window-only and the
    # window close button quits (still with confirmation) instead of hiding.
    tray_icon = app.create_tray_icon("hello-world", "Hello World", render_icon)

    app.run(tray_icon)


if __name__ == "__main__":
    main()

Run it

Save the above as hello_world.py and run python hello_world.py (it needs sevaht-gui and Pillow installed). The window opens centred; closing it hides to the tray, and Quit – from the tray’s right-click menu or by closing the window when there is no tray – asks for confirmation first.

What TkApp handled for you

  • Quit confirmation – the dialog is built, centred (flicker-free), and shown for you; you only supplied quit_confirm.

  • Tray menu and actions – left-click (or Open) shows the window, Quit confirms then exits.

  • Close-to-tray – the window’s close button hides it while a tray exists, and quits otherwise.

  • Centring and placement – centred on first show on the primary monitor, reopened where it was last moved.

  • Theme – a themed look with proper checkbox indicators.

  • Notificationsnotify() uses the tray when present and falls back to a standalone notifier otherwise, so the button works with or without a tray.

Next steps