PictureEdit/export_dialog.py
2025-09-02 16:49:39 +08:00

153 lines
5.8 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.

"""导出设置对话框"""
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
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()