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.
Notifications –
notify()uses the tray when present and falls back to a standalone notifier otherwise, so the button works with or without a tray.
Next steps¶
Pass a prepared image or a file path instead of a renderer; see
as_renderer().Keep the window and tray icons in sync with
set_app_icon(), or set them independently withset_window_icon()/set_tray_icon().Persist the window position across runs via
WindowPlacementand thewindow_positionproperty.