#!/usr/bin/env python # -*- coding: utf-8 -*- """UI控件模块 - StatusBar、ProgressReporter、可折叠框架等""" import tkinter as tk from tkinter import ttk from .theme import THEMES, get_theme_mode class StatusBar(tk.Frame): """状态栏,显示当前系统状态和进度""" def __init__(self, master, **kwargs): super().__init__(master, **kwargs) self.configure(height=25, relief=tk.SUNKEN, borderwidth=1) self.status_label = tk.Label(self, text="就绪", anchor=tk.W, padx=5) self.status_label.pack(side=tk.LEFT, fill=tk.X, expand=True) self.progress = ttk.Progressbar(self, orient=tk.HORIZONTAL, length=200, mode='determinate') self.progress.pack(side=tk.RIGHT, padx=5, pady=2) self.progress.pack_forget() def set_status(self, text, progress=None): """设置状态栏文本和进度""" self.status_label.config(text=text) if progress is not None and 0 <= progress <= 100: self.progress.pack(side=tk.RIGHT, padx=5, pady=2) self.progress.config(value=progress) else: self.progress.pack_forget() def set_running(self, is_running=True): """设置运行状态""" theme = THEMES[get_theme_mode()] if is_running: self.status_label.config(text="处理中...", foreground=theme["info"]) self.progress.pack(side=tk.RIGHT, padx=5, pady=2) self.progress.config(mode='indeterminate') self.progress.start() else: self.status_label.config(text="就绪", foreground=theme["fg"]) self.progress.stop() self.progress.pack_forget() class ProgressReporter: def __init__(self, status_bar: StatusBar): self.status_bar = status_bar def set(self, text: str, percent: int = None): try: if percent is not None: self.status_bar.set_status(text, percent) else: self.status_bar.set_status(text) except Exception: pass def running(self): try: self.status_bar.set_running(True) except Exception: pass def done(self): try: self.status_bar.set_running(False) self.status_bar.set_status("就绪") except Exception: pass def create_collapsible_frame(parent, title, initial_state=True): """创建可折叠的面板""" frame = tk.Frame(parent) frame.pack(fill=tk.X, pady=5) title_frame = tk.Frame(frame) title_frame.pack(fill=tk.X) state_var = tk.BooleanVar(value=initial_state) indicator = "▼" if initial_state else "►" state_label = tk.Label(title_frame, text=indicator, font=("Arial", 10, "bold")) state_label.pack(side=tk.LEFT, padx=5) title_label = tk.Label(title_frame, text=title, font=("Arial", 11, "bold")) title_label.pack(side=tk.LEFT, padx=5) content_frame = tk.Frame(frame) if initial_state: content_frame.pack(fill=tk.X, padx=20, pady=5) def toggle_collapse(event=None): current_state = state_var.get() new_state = not current_state state_var.set(new_state) state_label.config(text="▼" if new_state else "►") if new_state: content_frame.pack(fill=tk.X, padx=20, pady=5) else: content_frame.pack_forget() title_frame.bind("", toggle_collapse) state_label.bind("", toggle_collapse) title_label.bind("", toggle_collapse) return content_frame, state_var def center_window(window): """使窗口居中显示""" window.update_idletasks() width = window.winfo_width() height = window.winfo_height() x = (window.winfo_screenwidth() // 2) - (width // 2) y = (window.winfo_screenheight() // 2) - (height // 2) window.geometry('{}x{}+{}+{}'.format(width, height, x, y))