Files
shared_libs/log_window.py

102 lines
3.2 KiB
Python

import tkinter as tk
from tkinter import ttk
from datetime import datetime
import typing
from shared_libs.common_tools import IconManager
if typing.TYPE_CHECKING:
from tkinter import Event
class LogWindow(ttk.Frame):
"""A Tkinter frame that provides a scrollable text widget for logging messages."""
def __init__(self, parent: tk.Misc, copy: str = "Copy") -> None:
"""
Initializes the LogWindow widget.
Args:
parent: The parent widget.
copy: The text label for the 'Copy' context menu item.
"""
super().__init__(parent)
self.icon_manager = IconManager()
log_container = tk.Frame(self)
# Let the main app control padding via the grid options
log_container.pack(fill="both", expand=True, padx=0, pady=0)
self.log_text: tk.Text = tk.Text(
log_container,
wrap=tk.WORD,
font=("Consolas", 9),
bg="#1e1e1e",
fg="#d4d4d4",
insertbackground="white",
selectbackground="#264f78",
height=10 # Give it a default height
)
log_scrollbar = ttk.Scrollbar(
log_container, orient="vertical", command=self.log_text.yview
)
self.log_text.configure(yscrollcommand=log_scrollbar.set)
self.log_text.pack(side="left", fill="both", expand=True)
log_scrollbar.pack(side="right", fill="y")
self.context_menu: tk.Menu = tk.Menu(self, tearoff=0)
self.context_menu.add_command(
label=copy, command=self.copy_text, image=self.icon_manager.get_icon('copy'), compound='left')
self.log_text.bind("<Button-3>", self.show_context_menu)
def log_message(self, message: str) -> None:
"""
Adds a timestamped message to the log view.
Args:
message: The message string to add.
"""
timestamp = datetime.now().strftime("%H:%M:%S")
log_entry = f"[{timestamp}] {message}\n"
self.log_text.insert(tk.END, log_entry)
self.log_text.see(tk.END)
self.log_text.update()
def show_text_menu(self, event: 'Event') -> None:
"""
Displays the context menu at the event's coordinates.
(Note: This seems to be a remnant, show_context_menu is used).
Args:
event: The tkinter event that triggered the menu.
"""
try:
self.context_menu.tk_popup(event.x_root, event.y_root)
finally:
self.context_menu.grab_release()
def copy_text(self) -> None:
"""Copies the currently selected text in the log widget to the clipboard."""
try:
selected_text = self.log_text.selection_get()
self.clipboard_clear()
self.clipboard_append(selected_text)
except tk.TclError:
# No Text selected
pass
def show_context_menu(self, event: 'Event') -> None:
"""
Shows the right-click context menu.
Args:
event: The tkinter Button-3 event.
"""
try:
self.context_menu.tk_popup(event.x_root, event.y_root)
finally:
self.context_menu.grab_release()