#!/usr/bin/env python # -*- coding: utf-8 -*- """ 进度对话框组件 用于显示长时间运行操作的进度。 """ import tkinter as tk from tkinter import ttk from typing import Optional, Callable class ProgressDialog: """进度对话框""" def __init__( self, parent, title: str = "处理中...", message: str = "请稍候", can_cancel: bool = True, on_cancel: Optional[Callable] = None ): """ 初始化进度对话框 Args: parent: 父窗口 title: 对话框标题 message: 显示消息 can_cancel: 是否可以取消 on_cancel: 取消回调函数 """ self.parent = parent self.can_cancel = can_cancel self.on_cancel = on_cancel self.cancelled = False # 创建对话框 self.dialog = tk.Toplevel(parent) self.dialog.title(title) self.dialog.resizable(False, False) self.dialog.transient(parent) self.dialog.grab_set() # 居中显示 self._center() # 创建内容 self._create_widgets(message) def _center(self): """将对话框居中显示""" self.dialog.update_idletasks() width = 400 height = 150 x = (self.dialog.winfo_screenwidth() // 2) - (width // 2) y = (self.dialog.winfo_screenheight() // 2) - (height // 2) self.dialog.geometry(f"{width}x{height}+{x}+{y}") def _create_widgets(self, message: str): """创建对话框组件""" # 消息标签 self.message_label = ttk.Label(self.dialog, text=message, wraplength=380) self.message_label.pack(pady=(20, 10), padx=20) # 进度条 self.progress = ttk.Progressbar( self.dialog, mode='indeterminate', length=360 ) self.progress.pack(pady=10, padx=20) self.progress.start(10) # 取消按钮 if self.can_cancel: button_frame = ttk.Frame(self.dialog) button_frame.pack(pady=10) self.cancel_button = ttk.Button( button_frame, text="取消", command=self._on_cancel ) self.cancel_button.pack() def _on_cancel(self): """处理取消操作""" self.cancelled = True if self.on_cancel: self.on_cancel() self.close() def update_message(self, message: str): """更新显示消息""" self.message_label.config(text=message) self.dialog.update_idletasks() def set_progress(self, value: int, maximum: int = 100): """ 设置进度值 Args: value: 当前进度值 maximum: 最大值 """ self.progress.config(mode='determinate', maximum=maximum) self.progress['value'] = value self.dialog.update_idletasks() def close(self): """关闭对话框""" self.progress.stop() self.dialog.destroy() def is_cancelled(self) -> bool: """检查是否已取消""" return self.cancelled