Files
diskmanager2/logger_config_tkinter.py
2026-02-09 03:14:35 +08:00

85 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# logger_config_tkinter.py
import logging
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import queue
class TkinterLogHandler(logging.Handler):
"""
自定义的 logging 处理器,将日志消息发送到 Tkinter 文本控件。
使用队列确保线程安全。
"""
def __init__(self, text_widget: ScrolledText):
super().__init__()
self.text_widget = text_widget
self.queue = queue.Queue()
self._schedule_check()
def _schedule_check(self):
"""定期检查队列并更新 UI"""
self._check_queue()
# 每 100ms 检查一次队列
self.text_widget.after(100, self._schedule_check)
def _check_queue(self):
"""处理队列中的日志消息"""
try:
while True:
msg = self.queue.get_nowait()
self._append_to_widget(msg)
except queue.Empty:
pass
def _append_to_widget(self, msg):
"""将消息追加到文本控件"""
try:
self.text_widget.configure(state=tk.NORMAL)
self.text_widget.insert(tk.END, msg + '\n')
self.text_widget.see(tk.END) # 滚动到底部
self.text_widget.configure(state=tk.DISABLED)
except Exception as e:
# 如果控件已销毁,忽略错误
pass
def emit(self, record):
"""
处理日志记录,将其格式化并放入队列。
"""
try:
msg = self.format(record)
self.queue.put(msg)
except Exception:
self.handleError(record)
def setup_logging(text_widget: ScrolledText):
"""
配置全局 logging使其输出到控制台和指定的 Tkinter 文本控件。
"""
root_logger = logging.getLogger()
# 设置日志级别
root_logger.setLevel(logging.DEBUG)
# 清除现有的处理器
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
# 1. 控制台处理器
console_handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
root_logger.addHandler(console_handler)
# 2. Tkinter 文本控件处理器
text_handler = TkinterLogHandler(text_widget)
text_handler.setFormatter(formatter)
root_logger.addHandler(text_handler)
return root_logger
# 获取一个全局的 logger 实例
logger = logging.getLogger(__name__)