From f868be562f343ba37f8bf48ffd342125ff95bbe0 Mon Sep 17 00:00:00 2001 From: wsb1224 Date: Tue, 2 Sep 2025 18:14:12 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- canvas_widget.py | 3 ++- main_window.py | 24 +++++++++++++++---- models.py | 11 +++++---- template_dialog.py | 60 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/canvas_widget.py b/canvas_widget.py index 308c6c2..1447bb8 100644 --- a/canvas_widget.py +++ b/canvas_widget.py @@ -177,7 +177,8 @@ class CanvasWidget(tk.Canvas): # 绘制背景图(如果有) if self.project.template.bg_image: - bg_key = id(self.project.template.bg_image) + # 使用更稳定的缓存键,包含图像的标识和尺寸 + bg_key = (id(self.project.template.bg_image), template_w, template_h, self.zoom) if bg_key not in self.image_cache or self.image_cache[bg_key][0] != self.zoom: # 缩放背景图并缓存 scaled_bg = self.project.template.bg_image.resize( diff --git a/main_window.py b/main_window.py index 593e771..90ba252 100644 --- a/main_window.py +++ b/main_window.py @@ -264,19 +264,35 @@ class MainWindow(tk.Tk): """设置模板""" dialog = TemplateDialog(self, self.project.template) if dialog.result: - if dialog.result["type"] == "preset": + if dialog.result["type"] == "preset_loaded": + # 直接使用已加载的模板设置,不需要重新创建Template对象 + # 模板已经在对话框中加载完成,只需确保画布刷新 + pass + elif dialog.result["type"] == "preset": + # 确保传递所有参数并创建模板 self.project.template = Template( - dialog.result["ratio"], - dialog.result["width"] + ratio=tuple(dialog.result["ratio"]), + width_px=dialog.result["width"], + height_px=dialog.result.get("height") ) + # 设置背景颜色 + self.project.template.bg_color = dialog.result["bg_color"] + # 设置背景图 + if "bg_image" in dialog.result: + self.project.template.bg_image = dialog.result["bg_image"] else: self.project.template = Template() self.project.template.set_custom_size( dialog.result["width"], dialog.result["height"] ) + # 设置背景颜色 + self.project.template.bg_color = dialog.result["bg_color"] + # 设置背景图 + if "bg_image" in dialog.result: + self.project.template.bg_image = dialog.result["bg_image"] - self.project.template.bg_color = dialog.result["bg_color"] + # 确保更新画布显示 self.canvas.draw_preview() def batch_export(self): diff --git a/models.py b/models.py index 16fe18b..6503f46 100644 --- a/models.py +++ b/models.py @@ -119,10 +119,14 @@ class ForegroundImage: class Template: """模板对象,存储尺寸和背景信息""" - def __init__(self, ratio=(16, 9), width_px=1200): + def __init__(self, ratio=(16, 9), width_px=1200, height_px=None): self.ratio = ratio self.width_px = width_px - self.height_px = int(width_px * ratio[1] / ratio[0]) + # 如果提供了高度,使用提供的高度,否则根据比例计算 + if height_px is not None: + self.height_px = height_px + else: + self.height_px = int(width_px * ratio[1] / ratio[0]) self.bg_image = None self.bg_color = "#FFFFFF" # 默认白色背景 @@ -159,8 +163,7 @@ class Template: @classmethod def from_dict(cls, data): """从字典创建对象""" - template = cls(data["ratio"], data["width_px"]) - template.height_px = data["height_px"] + template = cls(data["ratio"], data["width_px"], data["height_px"]) template.bg_color = data.get("bg_color", "#FFFFFF") return template diff --git a/template_dialog.py b/template_dialog.py index a62e2c5..4e456f5 100644 --- a/template_dialog.py +++ b/template_dialog.py @@ -110,6 +110,8 @@ class TemplateDialog(tk.Toplevel): messagebox.showwarning("警告", "请先选择一个预设") return + # 设置标志以避免在刷新界面时更改尺寸 + self._loading_preset = True if self.preset_manager.load_preset_to_template(selected_preset, self.current_template): # 更新界面显示 self.refresh_from_template() @@ -118,6 +120,8 @@ class TemplateDialog(tk.Toplevel): messagebox.showinfo("成功", f"已加载预设: {selected_preset}") else: messagebox.showerror("错误", "加载预设失败") + # 清除标志 + self._loading_preset = False def save_current_as_preset(self): """将当前设置保存为预设""" @@ -177,10 +181,13 @@ class TemplateDialog(tk.Toplevel): self.show_custom_frame() else: self.hide_custom_frame() - # 设置默认尺寸 - w, h = map(int, self.ratio_var.get().split(":")) - self.width_var.set(1920 if w > h else 1080) - self.height_var.set(int(self.width_var.get() * h / w)) + # 仅在非预设加载情况下设置默认尺寸 + # 当从预设加载时,保持预设的尺寸不变 + if not (hasattr(self, '_loading_preset') and self._loading_preset): + # 设置默认尺寸 + w, h = map(int, self.ratio_var.get().split(":")) + self.width_var.set(1920 if w > h else 1080) + self.height_var.set(int(self.width_var.get() * h / w)) def show_custom_frame(self): """显示自定义尺寸框""" @@ -201,6 +208,8 @@ class TemplateDialog(tk.Toplevel): if file_path: if self.current_template.load_background(file_path): self.bg_image_var.set("已设置") + # 立即刷新画布预览 + self.parent.get_canvas().draw_preview() def clear_bg_image(self): """清除背景图""" @@ -212,7 +221,21 @@ class TemplateDialog(tk.Toplevel): # 如果选择了预设,则应用预设 selected_preset = self.preset_var.get() if selected_preset: - if not self.preset_manager.load_preset_to_template(selected_preset, self.current_template): + if self.preset_manager.load_preset_to_template(selected_preset, self.current_template): + # 刷新主窗口画布 + self.parent.get_canvas().draw_preview() + # 设置返回结果,包含预设的所有信息 + self.result = { + "type": "preset_loaded", # 修改类型以区分预设选择和预设加载 + "ratio": self.current_template.ratio, + "width": self.current_template.width_px, + "height": self.current_template.height_px, + "bg_color": self.current_template.bg_color, + "bg_image": self.current_template.bg_image + } + self.destroy() + return + else: messagebox.showerror("错误", "加载预设失败") return @@ -227,15 +250,18 @@ class TemplateDialog(tk.Toplevel): "type": "custom", "width": width, "height": height, - "bg_color": self.bg_color_var.get() + "bg_color": self.bg_color_var.get(), + "bg_image": self.current_template.bg_image } else: w, h = map(int, self.ratio_var.get().split(":")) self.result = { "type": "preset", - "ratio": (w, h), + "ratio": tuple([w, h]), "width": self.width_var.get(), - "bg_color": self.bg_color_var.get() + "height": self.height_var.get(), + "bg_color": self.bg_color_var.get(), + "bg_image": self.current_template.bg_image } self.destroy() except Exception as e: @@ -250,5 +276,23 @@ class TemplateDialog(tk.Toplevel): + + + + + + + + + + + + + + + + + +