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 }