🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Web Python Desktop Features Samples
Web Python desktop GUI examples including file dialogs, message boxes, and system tray functionality using tkinter
💻 Message Boxes python
🟢 simple
⭐⭐
Display various message boxes including info, warning, error, and question dialogs using tkinter.messagebox
⏱️ 20 min
🏷️ python, web, desktop, gui, message-box
Prerequisites:
Basic Python, tkinter module
# Web Python Message Boxes Examples
# Message and dialog boxes using tkinter.messagebox
#
# NOTE: These are desktop GUI features that require a desktop environment
# Install tkinter (usually included with Python):
# - Windows/Linux: Typically included with Python
# - macOS: brew install python-tk
#
# Run with: python message_boxes_examples.py
import tkinter as tk
from tkinter import messagebox, simpledialog
from typing import Optional, Any
# 1. Information Message Box
def show_info(
title: str = "Information",
message: str = "Operation completed successfully!",
parent: Optional[tk.Tk] = None
) -> None:
"""
Show an information message box
Args:
title: Dialog title
message: Message text
parent: Parent window (None creates new root)
"""
if parent is None:
root = tk.Tk()
root.withdraw()
messagebox.showinfo(title, message)
root.destroy()
else:
messagebox.showinfo(title, message, parent=parent)
# 2. Warning Message Box
def show_warning(
title: str = "Warning",
message: str = "Please be careful!",
parent: Optional[tk.Tk] = None
) -> None:
"""
Show a warning message box
Args:
title: Dialog title
message: Message text
parent: Parent window
"""
if parent is None:
root = tk.Tk()
root.withdraw()
messagebox.showwarning(title, message)
root.destroy()
else:
messagebox.showwarning(title, message, parent=parent)
# 3. Error Message Box
def show_error(
title: str = "Error",
message: str = "An error occurred!",
parent: Optional[tk.Tk] = None
) -> None:
"""
Show an error message box
Args:
title: Dialog title
message: Message text
parent: Parent window
"""
if parent is None:
root = tk.Tk()
root.withdraw()
messagebox.showerror(title, message)
root.destroy()
else:
messagebox.showerror(title, message, parent=parent)
# 4. Yes/No Question Box
def ask_yes_no(
title: str = "Confirm",
message: str = "Do you want to continue?",
parent: Optional[tk.Tk] = None
) -> bool:
"""
Show a yes/no question box
Args:
title: Dialog title
message: Question text
parent: Parent window
Returns:
True if Yes, False if No
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = messagebox.askyesno(title, message)
root.destroy()
return result
else:
return messagebox.askyesno(title, message, parent=parent)
# 5. OK/Cancel Question Box
def ask_ok_cancel(
title: str = "Confirm",
message: str = "Proceed with operation?",
parent: Optional[tk.Tk] = None
) -> bool:
"""
Show an OK/Cancel question box
Args:
title: Dialog title
message: Question text
parent: Parent window
Returns:
True if OK, False if Cancel
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = messagebox.askokcancel(title, message)
root.destroy()
return result
else:
return messagebox.askokcancel(title, message, parent=parent)
# 6. Yes/No/Cancel Question Box
def ask_yes_no_cancel(
title: str = "Confirm",
message: str = "Save changes before closing?",
parent: Optional[tk.Tk] = None
) -> Optional[bool]:
"""
Show a Yes/No/Cancel question box
Args:
title: Dialog title
message: Question text
parent: Parent window
Returns:
True if Yes, False if No, None if Cancel
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = messagebox.askyesnocancel(title, message)
root.destroy()
return result
else:
return messagebox.askyesnocancel(title, message, parent=parent)
# 7. Retry/Cancel Question Box
def ask_retry_cancel(
title: str = "Retry",
message: str = "Operation failed. Retry?",
parent: Optional[tk.Tk] = None
) -> bool:
"""
Show a Retry/Cancel question box
Args:
title: Dialog title
message: Question text
parent: Parent window
Returns:
True if Retry, False if Cancel
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = messagebox.askretrycancel(title, message)
root.destroy()
return result
else:
return messagebox.askretrycancel(title, message, parent=parent)
# 8. Simple String Input Dialog
def ask_string(
title: str = "Input",
prompt: str = "Enter value:",
initialvalue: Optional[str] = None,
parent: Optional[tk.Tk] = None
) -> Optional[str]:
"""
Show a string input dialog
Args:
title: Dialog title
prompt: Prompt text
initialvalue: Initial value
parent: Parent window
Returns:
Entered string or None if cancelled
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = simpledialog.askstring(title, prompt, initialvalue=initialvalue)
root.destroy()
return result
else:
return simpledialog.askstring(title, prompt, initialvalue=initialvalue, parent=parent)
# 9. Integer Input Dialog
def ask_integer(
title: str = "Input",
prompt: str = "Enter integer:",
initialvalue: Optional[int] = None,
minvalue: Optional[int] = None,
maxvalue: Optional[int] = None,
parent: Optional[tk.Tk] = None
) -> Optional[int]:
"""
Show an integer input dialog
Args:
title: Dialog title
prompt: Prompt text
initialvalue: Initial value
minvalue: Minimum value
maxvalue: Maximum value
parent: Parent window
Returns:
Entered integer or None if cancelled
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = simpledialog.askinteger(title, prompt, initialvalue=initialvalue, minvalue=minvalue, maxvalue=maxvalue)
root.destroy()
return result
else:
return simpledialog.askinteger(title, prompt, initialvalue=initialvalue, minvalue=minvalue, maxvalue=maxvalue, parent=parent)
# 10. Float Input Dialog
def ask_float(
title: str = "Input",
prompt: str = "Enter number:",
initialvalue: Optional[float] = None,
minvalue: Optional[float] = None,
maxvalue: Optional[float] = None,
parent: Optional[tk.Tk] = None
) -> Optional[float]:
"""
Show a float input dialog
Args:
title: Dialog title
prompt: Prompt text
initialvalue: Initial value
minvalue: Minimum value
maxvalue: Maximum value
parent: Parent window
Returns:
Entered float or None if cancelled
"""
if parent is None:
root = tk.Tk()
root.withdraw()
result = simpledialog.askfloat(title, prompt, initialvalue=initialvalue, minvalue=minvalue, maxvalue=maxvalue)
root.destroy()
return result
else:
return simpledialog.askfloat(title, prompt, initialvalue=initialvalue, minvalue=minvalue, maxvalue=maxvalue, parent=parent)
# 11. Custom Message Box with Icon
def show_custom_message(
title: str,
message: str,
icon: str = "info",
parent: Optional[tk.Tk] = None
) -> None:
"""
Show a custom message box with specified icon
Args:
title: Dialog title
message: Message text
icon: Icon type ('info', 'warning', 'error')
parent: Parent window
"""
if parent is None:
root = tk.Tk()
root.withdraw()
if icon == "info":
messagebox.showinfo(title, message)
elif icon == "warning":
messagebox.showwarning(title, message)
elif icon == "error":
messagebox.showerror(title, message)
else:
messagebox.showinfo(title, message)
root.destroy()
else:
if icon == "info":
messagebox.showinfo(title, message, parent=parent)
elif icon == "warning":
messagebox.showwarning(title, message, parent=parent)
elif icon == "error":
messagebox.showerror(title, message, parent=parent)
else:
messagebox.showinfo(title, message, parent=parent)
# 12. Confirmation Dialog Chain
def confirm_action(
steps: list,
parent: Optional[tk.Tk] = None
) -> bool:
"""
Show multiple confirmation dialogs in sequence
Args:
steps: List of (title, message) tuples
parent: Parent window
Returns:
True if all confirmed, False otherwise
"""
for title, message in steps:
if not ask_yes_no(title, message, parent):
return False
return True
# 13. Progress Message Box
class ProgressMessageBox:
"""Message box with progress indication"""
def __init__(self, title: str = "Progress", total: int = 100):
"""
Initialize progress message box
Args:
title: Window title
total: Total items to process
"""
self.root = tk.Tk()
self.root.title(title)
self.total = total
self.current = 0
self.label = tk.Label(self.root, text="Processing...")
self.label.pack(padx=20, pady=10)
self.progress = tk.Label(self.root, text=f"0 / {total}")
self.progress.pack(padx=20, pady=5)
def update(self, increment: int = 1) -> None:
"""
Update progress
Args:
increment: Amount to increment
"""
self.current += increment
self.progress.config(text=f"{self.current} / {self.total}")
self.root.update()
def close(self) -> None:
"""Close progress dialog"""
self.root.destroy()
# 14. Notification Popup
def show_notification(
title: str,
message: str,
duration: int = 3000
) -> None:
"""
Show a temporary notification popup
Args:
title: Notification title
message: Notification message
duration: Display duration in milliseconds
"""
root = tk.Tk()
root.title(title)
# Make window stay on top
root.attributes('-topmost', True)
# Remove window decorations
root.overrideredirect(True)
# Create message label
label = tk.Label(
root,
text=message,
bg='lightblue',
fg='black',
padx=20,
pady=10,
relief='raised',
borderwidth=2
)
label.pack()
# Center window
root.update_idletasks()
width = root.winfo_width()
height = root.winfo_height()
x = (root.winfo_screenwidth() // 2) - (width // 2)
y = 50 # Near top of screen
root.geometry(f'{width}x{height}+{x}+{y}')
# Auto-close after duration
root.after(duration, root.destroy)
root.mainloop()
# 15. Choice Dialog
def ask_choice(
title: str,
message: str,
choices: list,
parent: Optional[tk.Tk] = None
) -> Optional[str]:
"""
Show a choice selection dialog
Args:
title: Dialog title
message: Prompt message
choices: List of choices
parent: Parent window
Returns:
Selected choice or None
"""
root = tk.Tk() if parent is None else parent
if parent is None:
root.withdraw()
# Create custom dialog
dialog = tk.Toplevel(root)
dialog.title(title)
dialog.geometry("300x200")
# Message
label = tk.Label(dialog, text=message, wraplength=250)
label.pack(pady=10)
# Variable to store result
result = [None]
# Choice buttons
for choice in choices:
btn = tk.Button(
dialog,
text=choice,
command=lambda c=choice: set_result(c)
)
btn.pack(pady=5, padx=20, fill='x')
def set_result(value):
result[0] = value
dialog.destroy()
dialog.wait_window()
if parent is None:
root.destroy()
return result[0]
# Usage Examples
def demonstrate_message_boxes():
"""Demonstrate all message box examples"""
print("=== Python Message Boxes Examples ===\n")
# 1. Info box
print("--- 1. Information Message Box ---")
# show_info("Welcome", "This is an information message")
# 2. Warning box
print("\n--- 2. Warning Message Box ---")
# show_warning("Warning", "This is a warning message")
# 3. Error box
print("\n--- 3. Error Message Box ---")
# show_error("Error", "This is an error message")
# 4. Yes/No
print("\n--- 4. Yes/No Question ---")
# answer = ask_yes_no("Confirm", "Do you want to proceed?")
# print(f"User answered: {answer}")
# 5. OK/Cancel
print("\n--- 5. OK/Cancel Question ---")
# answer = ask_ok_cancel("Confirm", "Continue operation?")
# print(f"User answered: {answer}")
# 6. Yes/No/Cancel
print("\n--- 6. Yes/No/Cancel Question ---")
# answer = ask_yes_no_cancel("Save", "Save changes?")
# print(f"User answered: {answer}")
# 7. Retry/Cancel
print("\n--- 7. Retry/Cancel Question ---")
# answer = ask_retry_cancel("Retry", "Try again?")
# print(f"User answered: {answer}")
# 8. String input
print("\n--- 8. String Input Dialog ---")
# name = ask_string("Input", "Enter your name:")
# print(f"Name: {name}")
# 9. Integer input
print("\n--- 9. Integer Input Dialog ---")
# age = ask_integer("Input", "Enter your age:", minvalue=0, maxvalue=120)
# print(f"Age: {age}")
# 10. Float input
print("\n--- 10. Float Input Dialog ---")
# price = ask_float("Input", "Enter price:", minvalue=0.0)
# print(f"Price: {price}")
# 11. Custom icon
print("\n--- 11. Custom Icon Message ---")
# show_custom_message("Custom", "Message with custom icon", icon="warning")
# 12. Confirmation chain
print("\n--- 12. Confirmation Chain ---")
steps = [
("Step 1", "Confirm first step?"),
("Step 2", "Confirm second step?"),
("Step 3", "Confirm final step?")
]
# result = confirm_action(steps)
# print(f"All confirmed: {result}")
# 13. Progress box
print("\n--- 13. Progress Message Box ---")
# progress = ProgressMessageBox("Processing", total=10)
# for i in range(10):
# progress.update()
# time.sleep(0.5)
# progress.close()
# 14. Notification
print("\n--- 14. Notification Popup ---")
# show_notification("Notification", "Task completed!")
# 15. Choice dialog
print("\n--- 15. Choice Dialog ---")
# choice = ask_choice("Select", "Choose an option:", ["Option A", "Option B", "Option C"])
# print(f"Selected: {choice}")
print("\n=== All Message Box Examples Completed ===")
print("\nNOTE: Uncomment the dialog calls to see them in action")
print("GUI dialogs require a desktop environment")
# Export functions
export { show_info, show_warning, show_error }
export { ask_yes_no, ask_ok_cancel, ask_yes_no_cancel, ask_retry_cancel }
export { ask_string, ask_integer, ask_float }
export { show_custom_message, confirm_action, ProgressMessageBox }
export { show_notification, ask_choice }
export { demonstrate_message_boxes }
💻 File Dialogs python
🟡 intermediate
⭐⭐⭐
Open and save file dialogs, directory selection, and file information using tkinter.filedialog
⏱️ 30 min
🏷️ python, web, desktop, gui, file-dialog
Prerequisites:
Intermediate Python, tkinter module
# Web Python File Dialogs Examples
# File open/save dialogs using tkinter.filedialog
#
# NOTE: These are desktop GUI features that require a desktop environment
# Install tkinter (usually included with Python):
# - Windows/Linux: Typically included with Python
# - macOS: brew install python-tk
#
# Run with: python file_dialogs_examples.py
import tkinter as tk
from tkinter import filedialog, messagebox
from typing import Optional, List, Tuple
import os
from pathlib import Path
# 1. Open Single File Dialog
def open_single_file_dialog(
title: str = "Open File",
filetypes: Optional[List[Tuple[str, str]]] = None,
initialdir: Optional[str] = None
) -> Optional[str]:
"""
Open a dialog to select a single file
Args:
title: Dialog title
filetypes: List of file type filters, e.g., [("Text files", "*.txt"), ("All files", "*.*")]
initialdir: Initial directory to open
Returns:
Selected file path or None if cancelled
"""
root = tk.Tk()
root.withdraw() # Hide the main window
if filetypes is None:
filetypes = [("All files", "*.*")]
file_path = filedialog.askopenfilename(
title=title,
filetypes=filetypes,
initialdir=initialdir
)
root.destroy()
return file_path if file_path else None
# 2. Open Multiple Files Dialog
def open_multiple_files_dialog(
title: str = "Open Files",
filetypes: Optional[List[Tuple[str, str]]] = None,
initialdir: Optional[str] = None
) -> List[str]:
"""
Open a dialog to select multiple files
Args:
title: Dialog title
filetypes: List of file type filters
initialdir: Initial directory to open
Returns:
List of selected file paths or empty list if cancelled
"""
root = tk.Tk()
root.withdraw()
if filetypes is None:
filetypes = [("All files", "*.*")]
file_paths = filedialog.askopenfilenames(
title=title,
filetypes=filetypes,
initialdir=initialdir
)
root.destroy()
return list(file_paths) if file_paths else []
# 3. Save File Dialog
def save_file_dialog(
title: str = "Save File",
defaultextension: str = "",
filetypes: Optional[List[Tuple[str, str]]] = None,
initialdir: Optional[str] = None,
initialfile: Optional[str] = None
) -> Optional[str]:
"""
Open a dialog to save a file
Args:
title: Dialog title
defaultextension: Default extension to add if none provided
filetypes: List of file type filters
initialdir: Initial directory to open
initialfile: Suggested filename
Returns:
Selected file path or None if cancelled
"""
root = tk.Tk()
root.withdraw()
if filetypes is None:
filetypes = [("All files", "*.*")]
file_path = filedialog.asksaveasfilename(
title=title,
defaultextension=defaultextension,
filetypes=filetypes,
initialdir=initialdir,
initialfile=initialfile
)
root.destroy()
return file_path if file_path else None
# 4. Select Directory Dialog
def select_directory_dialog(
title: str = "Select Directory",
initialdir: Optional[str] = None,
mustexist: bool = True
) -> Optional[str]:
"""
Open a dialog to select a directory
Args:
title: Dialog title
initialdir: Initial directory to open
mustexist: Whether the directory must exist
Returns:
Selected directory path or None if cancelled
"""
root = tk.Tk()
root.withdraw()
directory = filedialog.askdirectory(
title=title,
initialdir=initialdir,
mustexist=mustexist
)
root.destroy()
return directory if directory else None
# 5. Custom File Filter
def create_common_file_filters() -> dict:
"""
Create common file type filters
Returns:
Dictionary of file type filters
"""
return {
'text': [("Text files", "*.txt"), ("All files", "*.*")],
'image': [("Image files", "*.png *.jpg *.jpeg *.gif *.bmp"), ("All files", "*.*")],
'document': [("Documents", "*.pdf *.doc *.docx *.txt"), ("All files", "*.*")],
'python': [("Python files", "*.py"), ("All files", "*.*")],
'json': [("JSON files", "*.json"), ("All files", "*.*")],
'csv': [("CSV files", "*.csv"), ("All files", "*.*")],
'all': [("All files", "*.*")]
}
# 6. File Information
def get_file_info(file_path: str) -> dict:
"""
Get information about a file
Args:
file_path: Path to the file
Returns:
Dictionary with file information
"""
try:
path = Path(file_path)
stat_info = path.stat()
return {
'name': path.name,
'stem': path.stem,
'suffix': path.suffix,
'parent': str(path.parent),
'size': stat_info.st_size,
'size_human': format_file_size(stat_info.st_size),
'created': stat_info.st_ctime,
'modified': stat_info.st_mtime,
'is_file': path.is_file(),
'is_dir': path.is_dir(),
'exists': path.exists(),
'absolute': str(path.absolute())
}
except Exception as e:
return {'error': str(e)}
def format_file_size(size_bytes: int) -> str:
"""
Format file size in human-readable format
Args:
size_bytes: Size in bytes
Returns:
Formatted size string
"""
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if size_bytes < 1024.0:
return f"{size_bytes:.2f} {unit}"
size_bytes /= 1024.0
return f"{size_bytes:.2f} PB"
# 7. Batch File Operations
def batch_open_files(max_files: int = 10) -> List[str]:
"""
Open multiple files with a limit
Args:
max_files: Maximum number of files to select
Returns:
List of selected file paths
"""
root = tk.Tk()
root.withdraw()
file_paths = filedialog.askopenfilenames(title=f"Select up to {max_files} files")
root.destroy()
if file_paths:
paths = list(file_paths)
if len(paths) > max_files:
messagebox.showwarning(
"Too Many Files",
f"You selected {len(paths)} files. Only the first {max_files} will be used."
)
return paths[:max_files]
return paths
return []
# 8. File Dialog with Preview
def open_file_with_validation(
allowed_extensions: List[str],
min_size: int = 0,
max_size: int = 1024 * 1024 * 100 # 100 MB
) -> Optional[str]:
"""
Open file dialog with validation
Args:
allowed_extensions: List of allowed extensions (e.g., ['.txt', '.py'])
min_size: Minimum file size in bytes
max_size: Maximum file size in bytes
Returns:
Validated file path or None
"""
file_path = open_single_file_dialog()
if not file_path:
return None
# Validate extension
file_ext = Path(file_path).suffix.lower()
if allowed_extensions and file_ext not in [ext.lower() for ext in allowed_extensions]:
messagebox.showerror(
"Invalid File Type",
f"File must be one of: {', '.join(allowed_extensions)}"
)
return None
# Validate size
file_size = Path(file_path).stat().st_size
if file_size < min_size or file_size > max_size:
messagebox.showerror(
"Invalid File Size",
f"File size must be between {min_size} and {max_size} bytes"
)
return None
return file_path
# 9. Recent Files Dialog
class RecentFilesManager:
"""Manager for recent files"""
def __init__(self, max_files: int = 10):
"""
Initialize recent files manager
Args:
max_files: Maximum number of recent files to track
"""
self.max_files = max_files
self.recent_files: List[str] = []
def add_file(self, file_path: str) -> None:
"""
Add a file to recent files
Args:
file_path: Path to add
"""
if file_path in self.recent_files:
self.recent_files.remove(file_path)
self.recent_files.insert(0, file_path)
if len(self.recent_files) > self.max_files:
self.recent_files = self.recent_files[:self.max_files]
def get_recent_files(self) -> List[str]:
"""Get list of recent files"""
return self.recent_files.copy()
def clear_recent(self) -> None:
"""Clear recent files list"""
self.recent_files.clear()
# 10. Advanced File Dialog
def advanced_file_dialog(
mode: str = 'open',
filters: Optional[List[Tuple[str, str]]] = None,
initial_dir: Optional[str] = None,
initial_file: Optional[str] = None
) -> Optional[str]:
"""
Advanced file dialog with multiple modes
Args:
mode: Dialog mode ('open', 'save', 'directory')
filters: File type filters
initial_dir: Initial directory
initial_file: Initial filename (for save mode)
Returns:
Selected path or None
"""
root = tk.Tk()
root.withdraw()
if filters is None:
filters = [("All files", "*.*")]
result = None
if mode == 'open':
result = filedialog.askopenfilename(
title="Open File",
filetypes=filters,
initialdir=initial_dir
)
elif mode == 'save':
result = filedialog.asksaveasfilename(
title="Save File",
filetypes=filters,
initialdir=initial_dir,
initialfile=initial_file
)
elif mode == 'directory':
result = filedialog.askdirectory(
title="Select Directory",
initialdir=initial_dir
)
root.destroy()
return result if result else None
# Usage Examples
def demonstrate_file_dialogs():
"""Demonstrate all file dialog examples"""
print("=== Python File Dialogs Examples ===\n")
# 1. Open single file
print("--- 1. Open Single File Dialog ---")
print("Opening file selection dialog...")
# file = open_single_file_dialog(title="Select a Text File", filetypes=[("Text files", "*.txt")])
# print(f"Selected: {file}")
# 2. Open multiple files
print("\n--- 2. Open Multiple Files Dialog ---")
print("Opening multiple file selection dialog...")
# files = open_multiple_files_dialog(title="Select Files")
# print(f"Selected {len(files)} files")
# 3. Save file
print("\n--- 3. Save File Dialog ---")
print("Opening save file dialog...")
# saved = save_file_dialog(title="Save As", defaultextension=".txt")
# print(f"Save to: {saved}")
# 4. Select directory
print("\n--- 4. Select Directory Dialog ---")
print("Opening directory selection dialog...")
# directory = select_directory_dialog(title="Select Working Directory")
# print(f"Selected: {directory}")
# 5. Custom filters
print("\n--- 5. Custom File Filters ---")
filters = create_common_file_filters()
print(f"Available filter types: {list(filters.keys())}")
# 6. File info
print("\n--- 6. File Information ---")
# if file:
# info = get_file_info(file)
# print(f"File info: {info}")
# 7. Batch operations
print("\n--- 7. Batch File Operations ---")
print("Can select multiple files with limits")
# 8. Validation
print("\n--- 8. File Validation ---")
print("Validates file type and size")
# 9. Recent files
print("\n--- 9. Recent Files Manager ---")
recent = RecentFilesManager()
recent.add_file("/path/to/file1.txt")
recent.add_file("/path/to/file2.py")
print(f"Recent files: {recent.get_recent_files()}")
# 10. Advanced dialog
print("\n--- 10. Advanced File Dialog ---")
print("Multi-mode dialog: open, save, directory")
print("\n=== All File Dialog Examples Completed ===")
print("\nNOTE: Uncomment the dialog calls to see them in action")
print("GUI dialogs require a desktop environment")
# Export functions
export { open_single_file_dialog, open_multiple_files_dialog }
export { save_file_dialog, select_directory_dialog }
export { create_common_file_filters, get_file_info, format_file_size }
export { batch_open_files, open_file_with_validation }
export { RecentFilesManager, advanced_file_dialog }
export { demonstrate_file_dialogs }
💻 System Tray python
🔴 complex
⭐⭐⭐⭐
Create system tray icons with menus, notifications, and window management
⏱️ 45 min
🏷️ python, web, desktop, gui, system-tray
Prerequisites:
Advanced Python, pystray, Pillow, Threading
# Web Python System Tray Examples
# System tray icon and menu functionality
#
# NOTE: These are desktop GUI features that require a desktop environment
# Install required packages:
# pip install pystray Pillow
#
# For Linux: Additional requirements
# - Ubuntu/Debian: sudo apt-get install python3-tk gir1.2-appindicator3-0.1
# - Fedora: sudo dnf install python3-gobject python3-appindicator
#
# Run with: python system_tray_examples.py
import tkinter as tk
from threading import Thread
import time
from typing import Callable, Optional, List
from PIL import Image, ImageDraw
import sys
# Try to import pystray, provide fallback if not available
try:
import pystray
PYSTRAY_AVAILABLE = True
except ImportError:
PYSTRAY_AVAILABLE = False
print("Warning: pystray not available. Install with: pip install pystray Pillow")
# 1. Create Simple Tray Icon
def create_simple_icon(
icon_name: str = "Simple App",
menu_items: Optional[List[tuple]] = None,
on_click: Optional[Callable] = None
) -> Optional['pystray.Icon']:
"""
Create a simple system tray icon
Args:
icon_name: Name/tooltip for the icon
menu_items: List of (label, callback) tuples
on_click: Single click callback
Returns:
Icon object or None if pystray unavailable
"""
if not PYSTRAY_AVAILABLE:
print("pystray is required for system tray functionality")
return None
# Create a simple icon image
image = create_icon_image((64, 64), color='blue')
# Create menu
if menu_items is None:
menu_items = [
('Show', lambda: print("Show clicked")),
('Hide', lambda: print("Hide clicked")),
('Exit', lambda: exit_app())
]
menu = pystray.Menu(
*[pystray.MenuItem(label, callback) for label, callback in menu_items]
)
# Create icon
icon = pystray.Icon(icon_name, image, menu=menu)
# Set default click action
if on_click:
icon.on_click = on_click
return icon
# 2. Create Icon Image
def create_icon_image(
size: tuple = (64, 64),
color: str = 'blue',
text: Optional[str] = None
) -> 'Image.Image':
"""
Create an icon image
Args:
size: Image size (width, height)
color: Background color
text: Optional text to draw on icon
Returns:
PIL Image object
"""
width, height = size
image = Image.new('RGB', size, color)
draw = ImageDraw.Draw(image)
if text:
# Draw text centered
from PIL import ImageFont
try:
font = ImageFont.truetype("arial.ttf", 20)
except:
font = ImageFont.load_default()
# Get text bounding box
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
# Calculate position
x = (width - text_width) // 2
y = (height - text_height) // 2
draw.text((x, y), text, fill='white', font=font)
else:
# Draw a simple circle
margin = 5
draw.ellipse(
[margin, margin, width - margin, height - margin],
fill='white',
outline=color
)
return image
# 3. Animated Tray Icon
class AnimatedTrayIcon:
"""System tray icon with animation"""
def __init__(
self,
icon_name: str = "Animated Icon",
colors: List[str] = None,
interval: float = 0.5
):
"""
Initialize animated tray icon
Args:
icon_name: Name for the icon
colors: List of colors to cycle through
interval: Animation interval in seconds
"""
if not PYSTRAY_AVAILABLE:
raise ImportError("pystray is required")
self.icon_name = icon_name
self.colors = colors or ['red', 'green', 'blue']
self.interval = interval
self.current_frame = 0
self.running = False
# Create initial icon
self.image = create_icon_image(color=self.colors[0])
self.icon = pystray.Icon(self.icon_name, self.image)
def next_frame(self):
"""Advance to next animation frame"""
self.current_frame = (self.current_frame + 1) % len(self.colors)
self.icon.icon = create_icon_image(color=self.colors[self.current_frame])
def run_animation(self):
"""Run animation loop"""
self.running = True
while self.running:
self.next_frame()
time.sleep(self.interval)
def start(self):
"""Start the icon with animation"""
# Start animation in separate thread
animation_thread = Thread(target=self.run_animation, daemon=True)
animation_thread.start()
# Run icon
self.icon.run()
def stop(self):
"""Stop animation and icon"""
self.running = False
self.icon.stop()
# 4. Tray Icon with Window Management
class TrayApp:
"""Application with system tray integration"""
def __init__(
self,
window_title: str = "Tray App",
icon_name: str = "My App"
):
"""
Initialize tray application
Args:
window_title: Main window title
icon_name: Tray icon name
"""
if not PYSTRAY_AVAILABLE:
raise ImportError("pystray is required")
self.window_title = window_title
self.icon_name = icon_name
self.window = None
self.icon = None
self.visible = True
def create_window(self):
"""Create main application window"""
self.window = tk.Tk()
self.window.title(self.window_title)
self.window.geometry("400x300")
# Add content
label = tk.Label(
self.window,
text=f"{self.window_title}\n\nMinimize me to tray!",
font=('Arial', 14)
)
label.pack(expand=True)
# Handle window close
self.window.protocol("WM_DELETE_WINDOW", self.on_window_close)
def on_window_close(self):
"""Handle window close - minimize to tray"""
self.window.withdraw()
self.visible = False
def show_window(self):
"""Show and restore window"""
if self.window is None:
self.create_window()
self.window.deiconify()
self.window.lift()
self.visible = True
def hide_window(self):
"""Hide window"""
if self.window:
self.window.withdraw()
self.visible = False
def toggle_window(self):
"""Toggle window visibility"""
if self.visible:
self.hide_window()
else:
self.show_window()
def exit_app(self):
"""Exit application"""
if self.window:
self.window.destroy()
if self.icon:
self.icon.stop()
sys.exit(0)
def run(self):
"""Run the application"""
# Create window
self.create_window()
# Create tray icon
image = create_icon_image(color='green')
# Create menu
menu = pystray.Menu(
pystray.MenuItem('Show', self.show_window),
pystray.MenuItem('Hide', self.hide_window),
pystray.MenuItem('Exit', self.exit_app)
)
# Create icon
self.icon = pystray.Icon(
self.icon_name,
image,
menu=menu
)
# Set double-click to show window
def on_double_click(icon, button, time):
if button == pystray.MouseButton.LEFT:
self.toggle_window()
self.icon.on_double_click = on_double_click
# Run icon in separate thread
icon_thread = Thread(target=self.icon.run, daemon=True)
icon_thread.start()
# Run window main loop
self.window.mainloop()
# 5. Tray Icon with Notifications
class NotificationTrayIcon:
"""System tray icon with notification support"""
def __init__(
self,
icon_name: str = "Notifier",
default_notification: str = "No new notifications"
):
"""
Initialize notification tray icon
Args:
icon_name: Icon name
default_notification: Default message
"""
if not PYSTRAY_AVAILABLE:
raise ImportError("pystray is required")
self.icon_name = icon_name
self.notifications = []
self.default_notification = default_notification
# Create icon
image = create_icon_image(color='orange')
self.icon = pystray.Icon(
self.icon_name,
image,
title=self.default_notification
)
# Setup menu
self.setup_menu()
def setup_menu(self):
"""Setup tray menu"""
menu = pystray.Menu(
pystray.MenuItem('Show Notifications', self.show_notifications),
pystray.MenuItem('Clear Notifications', self.clear_notifications),
pystray.MenuItem('Exit', self.exit_app)
)
self.icon.menu = menu
def add_notification(self, message: str):
"""
Add a notification
Args:
message: Notification message
"""
self.notifications.append({
'message': message,
'time': time.ctime()
})
# Update icon tooltip
self.icon.title = f"{len(self.notifications)} new notifications"
# Update icon to show notification state
self.icon.icon = create_icon_image(color='red', text=str(len(self.notifications)))
def show_notifications(self):
"""Show all notifications"""
if not self.notifications:
print("No notifications")
return
# Create popup window
root = tk.Tk()
root.title("Notifications")
root.geometry("400x300")
text = tk.Text(root, wrap='word')
text.pack(expand=True, fill='both', padx=10, pady=10)
for notif in self.notifications:
text.insert('end', f"[{notif['time']}]\n{notif['message']}\n\n")
text.config(state='disabled')
# Close button
btn = tk.Button(root, text="Close", command=root.destroy)
btn.pack(pady=5)
root.mainloop()
def clear_notifications(self):
"""Clear all notifications"""
self.notifications.clear()
self.icon.title = self.default_notification
self.icon.icon = create_icon_image(color='orange')
def exit_app(self):
"""Exit application"""
self.icon.stop()
sys.exit(0)
def run(self):
"""Run the icon"""
self.icon.run()
# 6. Tray Icon with Status Indicator
class StatusTrayIcon:
"""System tray icon with status indicator"""
STATUS_COLORS = {
'online': 'green',
'offline': 'gray',
'busy': 'red',
'away': 'yellow',
'error': 'darkred'
}
def __init__(self, icon_name: str = "Status App"):
"""
Initialize status tray icon
Args:
icon_name: Icon name
"""
if not PYSTRAY_AVAILABLE:
raise ImportError("pystray is required")
self.icon_name = icon_name
self.current_status = 'offline'
# Create icon
image = create_icon_image(color=self.STATUS_COLORS[self.current_status])
self.icon = pystray.Icon(
self.icon_name,
image,
title=f"Status: {self.current_status}"
)
# Setup menu with status options
self.setup_menu()
def setup_menu(self):
"""Setup menu with status options"""
menu_items = []
for status in self.STATUS_COLORS.keys():
menu_items.append(
pystray.MenuItem(
status.capitalize(),
lambda s=status: self.set_status(s)
)
)
menu_items.append(pystray.MenuItem('Exit', self.exit_app))
self.icon.menu = pystray.Menu(*menu_items)
def set_status(self, status: str):
"""
Set current status
Args:
status: Status to set
"""
if status in self.STATUS_COLORS:
self.current_status = status
self.icon.icon = create_icon_image(
color=self.STATUS_COLORS[status],
text=status[0].upper()
)
self.icon.title = f"Status: {status}"
print(f"Status changed to: {status}")
def exit_app(self):
"""Exit application"""
self.icon.stop()
sys.exit(0)
def run(self):
"""Run the icon"""
self.icon.run()
# 7. Quick Actions Tray Icon
class QuickActionsTrayIcon:
"""System tray icon with quick actions"""
def __init__(self, icon_name: str = "Quick Actions"):
"""
Initialize quick actions tray icon
Args:
icon_name: Icon name
"""
if not PYSTRAY_AVAILABLE:
raise ImportError("pystray is required")
self.icon_name = icon_name
self.actions = {
'Screenshot': self.take_screenshot,
'Open Calculator': self.open_calculator,
'Open Notepad': self.open_notepad,
'Lock Screen': self.lock_screen
}
# Create icon
image = create_icon_image(color='purple')
self.icon = pystray.Icon(self.icon_name, image)
# Setup menu with actions
self.setup_menu()
def setup_menu(self):
"""Setup menu with quick actions"""
menu_items = [
pystray.MenuItem(label, callback)
for label, callback in self.actions.items()
]
menu_items.append(pystray.MenuItem('Exit', self.exit_app))
self.icon.menu = pystray.Menu(*menu_items)
def take_screenshot(self):
"""Take a screenshot"""
print("Screenshot action triggered")
# Implementation would use PIL.ImageGrab or similar
def open_calculator(self):
"""Open calculator"""
import subprocess
try:
if sys.platform == 'win32':
subprocess.Popen('calc.exe')
elif sys.platform == 'darwin':
subprocess.Popen(['open', '-a', 'Calculator'])
else:
subprocess.Popen('gnome-calculator')
except Exception as e:
print(f"Error opening calculator: {e}")
def open_notepad(self):
"""Open notepad"""
import subprocess
try:
if sys.platform == 'win32':
subprocess.Popen('notepad.exe')
elif sys.platform == 'darwin':
subprocess.Popen(['open', '-a', 'TextEdit'])
else:
subprocess.Popen('gedit')
except Exception as e:
print(f"Error opening notepad: {e}")
def lock_screen(self):
"""Lock screen"""
import subprocess
try:
if sys.platform == 'win32':
subprocess.Popen('rundll32.exe user32.dll,LockWorkStation')
elif sys.platform == 'darwin':
subprocess.Popen(['pmset', 'displaysleepnow'])
else:
subprocess.Popen(['gnome-screensaver-command', '-l'])
except Exception as e:
print(f"Error locking screen: {e}")
def exit_app(self):
"""Exit application"""
self.icon.stop()
sys.exit(0)
def run(self):
"""Run the icon"""
self.icon.run()
# Usage Examples
def demonstrate_system_tray():
"""Demonstrate system tray functionality"""
print("=== Python System Tray Examples ===\n")
if not PYSTRAY_AVAILABLE:
print("pystray is not installed. Install with:")
print(" pip install pystray Pillow")
print("\nSkipping system tray demonstrations.\n")
return
print("System tray functionality available!")
print("\nChoose an example to run:")
print("1. Simple Tray Icon")
print("2. Animated Tray Icon")
print("3. Tray App with Window Management")
print("4. Notification Tray Icon")
print("5. Status Indicator Tray Icon")
print("6. Quick Actions Tray Icon")
print("\nNOTE: Uncomment the example you want to run")
# Example 1: Simple icon
# icon = create_simple_icon("My App")
# if icon:
# icon.run()
# Example 2: Animated icon
# animated = AnimatedTrayIcon("Animated", colors=['red', 'green', 'blue'])
# animated.start()
# Example 3: Window management
# app = TrayApp("My Application", "MyApp")
# app.run()
# Example 4: Notifications
# notifier = NotificationTrayIcon("Notifier")
# notifier.add_notification("Welcome to the app!")
# notifier.add_notification("New message received")
# notifier.run()
# Example 5: Status indicator
# status = StatusTrayIcon("StatusApp")
# status.run()
# Example 6: Quick actions
# actions = QuickActionsTrayIcon("QuickActions")
# actions.run()
print("\n=== System Tray Examples Completed ===")
# Export functions
export { create_simple_icon, create_icon_image }
export { AnimatedTrayIcon, TrayApp, NotificationTrayIcon }
export { StatusTrayIcon, QuickActionsTrayIcon }
export { demonstrate_system_tray }
export { PYSTRAY_AVAILABLE }