"""导出设置对话框""" """ 作者:太一 微信:taiyi1224 邮箱:shuobo1224@qq.com """ """ 作者:太一 微信:taiyi1224 邮箱:shuobo1224@qq.com """ import tkinter as tk from tkinter import ttk, filedialog, messagebox import os from pathlib import Path from exporter import Exporter class ExportDialog(tk.Toplevel): def __init__(self, parent, count): super().__init__(parent) self.title("导出设置") self.parent = parent self.count = count self.result = None # 确保对话框模态 self.transient(parent) self.grab_set() # 设置默认导出路径为第一个图片所在目录下的output文件夹 default_output_dir = str(Path.home()) if parent.project.foregrounds: first_image_dir = Path(parent.project.foregrounds[0].file_path).parent default_output_dir = first_image_dir / "output" # 设置布局 frame = ttk.Frame(self, padding=10) frame.pack(fill=tk.BOTH, expand=True) # 输出目录 ttk.Label(frame, text="输出目录:").grid(row=0, column=0, sticky=tk.W, pady=5) self.output_dir_var = tk.StringVar(value=str(default_output_dir)) ttk.Entry(frame, textvariable=self.output_dir_var, width=50).grid(row=0, column=1, pady=5) ttk.Button(frame, text="浏览", command=self.choose_output_dir).grid(row=0, column=2, padx=5, pady=5) # 文件名模板 ttk.Label(frame, text="文件名模板:").grid(row=1, column=0, sticky=tk.W, pady=5) self.filename_var = tk.StringVar(value="{name}_{idx}") ttk.Entry(frame, textvariable=self.filename_var, width=50).grid(row=1, column=1, pady=5) ttk.Label(frame, text="可用变量: {name}, {idx}, {total}, {date}").grid(row=1, column=2, pady=5) # 输出格式 ttk.Label(frame, text="输出格式:").grid(row=2, column=0, sticky=tk.W, pady=5) self.format_var = tk.StringVar(value="png") format_frame = ttk.Frame(frame) ttk.Radiobutton(format_frame, text="PNG", variable=self.format_var, value="png").pack(side=tk.LEFT, padx=5) ttk.Radiobutton(format_frame, text="JPEG", variable=self.format_var, value="jpeg").pack(side=tk.LEFT, padx=5) format_frame.grid(row=2, column=1, sticky=tk.W, pady=5) # 质量设置(仅JPEG) self.quality_frame = ttk.Frame(frame) ttk.Label(self.quality_frame, text="质量:").pack(side=tk.LEFT, padx=5) self.quality_var = tk.IntVar(value=95) ttk.Scale( self.quality_frame, from_=1, to=100, variable=self.quality_var, orient=tk.HORIZONTAL, length=200, command=lambda v: self.quality_label.config(text=f"{int(float(v))}%") ).pack(side=tk.LEFT, padx=5) self.quality_label = ttk.Label(self.quality_frame, text="95%") self.quality_label.pack(side=tk.LEFT, padx=5) # 进度条 self.progress_var = tk.DoubleVar(value=0) self.progress_bar = ttk.Progressbar(frame, variable=self.progress_var, maximum=100) # 按钮 btn_frame = ttk.Frame(frame) self.export_btn = ttk.Button(btn_frame, text="导出", command=self.on_export) self.export_btn.pack(side=tk.LEFT, padx=5) ttk.Button(btn_frame, text="取消", command=self.on_cancel).pack(side=tk.LEFT, padx=5) # 根据格式显示/隐藏质量设置 self.update_quality_visibility() self.format_var.trace_add("write", lambda *args: self.update_quality_visibility()) # 布局管理 self.quality_frame.grid(row=3, column=0, columnspan=3, sticky=tk.W, pady=5) self.progress_bar.grid(row=4, column=0, columnspan=2, sticky=tk.EW, pady=5) btn_frame.grid(row=5, column=0, columnspan=3, pady=10) # 调整大小 self.geometry("700x300") self.wait_window(self) def choose_output_dir(self): """选择输出目录""" dir_path = filedialog.askdirectory() if dir_path: self.output_dir_var.set(dir_path) def update_quality_visibility(self): """根据输出格式显示或隐藏质量设置""" if self.format_var.get().lower() == "jpeg": self.quality_frame.grid() else: self.quality_frame.grid_forget() def update_progress(self, current, total): """更新进度条""" progress = (current / total) * 100 self.progress_var.set(progress) self.update_idletasks() def on_export(self): """执行导出""" # 禁用导出按钮防止重复点击 self.export_btn.config(state=tk.DISABLED) # 在新线程中执行导出,避免阻塞UI import threading export_thread = threading.Thread(target=self._perform_export) export_thread.daemon = True export_thread.start() def _perform_export(self): """在后台线程中执行导出""" output_dir = self.output_dir_var.get() filename_template = self.filename_var.get() format = self.format_var.get() quality = self.quality_var.get() # 执行导出 success = Exporter.export_batch( self.parent.project, output_dir, filename_template, format, quality, progress_callback=self.update_progress ) # 在主线程中更新UI self.after(0, self._on_export_complete, success) def _on_export_complete(self, success): """导出完成后的回调""" if success: messagebox.showinfo("成功", f"已成功导出 {self.count} 张图片") self.result = True self.destroy() else: messagebox.showerror("错误", "导出过程中发生错误") self.export_btn.config(state=tk.NORMAL) def on_cancel(self): """取消导出""" self.result = None self.destroy()