153 lines
5.8 KiB
Python
153 lines
5.8 KiB
Python
|
|
"""导出设置对话框"""
|
|||
|
|
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()
|