PictureEdit/export_dialog.py

166 lines
5.9 KiB
Python
Raw Normal View History

2025-09-02 16:49:39 +08:00
"""导出设置对话框"""
2025-09-04 12:55:33 +08:00
"""
作者太一
微信taiyi1224
邮箱shuobo1224@qq.com
"""
"""
作者太一
微信taiyi1224
邮箱shuobo1224@qq.com
"""
2025-09-02 16:49:39 +08:00
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
2025-09-04 12:55:33 +08:00
import os
2025-09-02 16:49:39 +08:00
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()