修改引用逻辑、新增Pattern更改界面、新增Calman灰阶界面

This commit is contained in:
xinzhu.yin
2026-05-27 11:26:28 +08:00
parent a903c17cb3
commit dff4e0df4d
24 changed files with 3327 additions and 386 deletions

View File

@@ -14,13 +14,19 @@ from PIL import Image, ImageTk
from app.services import ai_image as _svc
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from pqAutomationApp import PQAutomationApp
# ---------------- 面板创建 ----------------
def create_ai_image_panel(self):
def create_ai_image_panel(self: "PQAutomationApp"):
"""创建 AI 图片对话面板,并注册到面板管理。"""
frame = ttk.Frame(self.content_frame)
self.ai_image_frame = frame
@@ -190,12 +196,12 @@ def create_ai_image_panel(self):
reload_ai_image_list(self)
def toggle_ai_image_panel(self):
def toggle_ai_image_panel(self: "PQAutomationApp"):
"""切换 AI 图片面板显隐。"""
self.show_panel("ai_image")
def _get_app_base_dir(self) -> str:
def _get_app_base_dir(self: "PQAutomationApp") -> str:
"""返回应用根目录settings 的上一级)。"""
if getattr(self, "config_file", None):
return os.path.dirname(os.path.dirname(self.config_file))
@@ -207,7 +213,7 @@ def _get_app_base_dir(self) -> str:
# ---------------- 列表 / 选中 ----------------
def reload_ai_image_list(self, auto_select_first=True):
def reload_ai_image_list(self: "PQAutomationApp", auto_select_first=True):
"""重新扫描缓存并刷新列表。
按 ``session_id`` 分组:每个会话用一行不可选的分隔头(``── 会话 #N · 时间 ──``
@@ -289,7 +295,7 @@ def _format_list_label(rec: _svc.AIImageRecord) -> str:
return f"{size_tag}{name_line}"
def _on_list_select(self):
def _on_list_select(self: "PQAutomationApp"):
sel = self.ai_image_listbox.curselection()
if not sel:
return
@@ -311,7 +317,7 @@ def _on_list_select(self):
_select_record(self, rec)
def _select_record(self, rec: _svc.AIImageRecord):
def _select_record(self: "PQAutomationApp", rec: _svc.AIImageRecord):
self.ai_image_current = rec
self.ai_image_meta_var.set(
f"{os.path.basename(rec.image_path)} | {rec.created_at}"
@@ -322,7 +328,7 @@ def _select_record(self, rec: _svc.AIImageRecord):
# ---------------- 预览绘制 ----------------
def _redraw_preview(self):
def _redraw_preview(self: "PQAutomationApp"):
rec = getattr(self, "ai_image_current", None)
canvas = self.ai_image_canvas
canvas.delete("all")
@@ -347,7 +353,7 @@ def _redraw_preview(self):
# ---------------- 发送 / 保存 / 删除 ----------------
def _start_new_session(self):
def _start_new_session(self: "PQAutomationApp"):
"""开启新的对话会话,后续生成将使用新的 session_id。"""
if getattr(self, "_ai_image_requesting", False):
messagebox.showinfo("提示", "请等待当前请求完成")
@@ -357,14 +363,14 @@ def _start_new_session(self):
reload_ai_image_list(self, auto_select_first=False)
def _session_id_for_row(self, row: int) -> str:
def _session_id_for_row(self: "PQAutomationApp", row: int) -> str:
session_map = getattr(self, "_ai_image_row_session_map", None) or []
if row < 0 or row >= len(session_map):
return ""
return session_map[row] or ""
def _switch_to_session(self, session_id: str, show_message: bool = True, target_record_id: str = ""):
def _switch_to_session(self: "PQAutomationApp", session_id: str, show_message: bool = True, target_record_id: str = ""):
sid = (session_id or "").strip()
if not sid:
return
@@ -389,7 +395,7 @@ def _switch_to_session(self, session_id: str, show_message: bool = True, target_
messagebox.showinfo("提示", "已切换到所选历史对话")
def _update_request_progress(self):
def _update_request_progress(self: "PQAutomationApp"):
if not getattr(self, "_ai_image_requesting", False):
self._ai_image_progress_job = None
return
@@ -398,7 +404,7 @@ def _update_request_progress(self):
self._ai_image_progress_job = self.root.after(900, lambda: _update_request_progress(self))
def _send_prompt(self):
def _send_prompt(self: "PQAutomationApp"):
if getattr(self, "_ai_image_requesting", False):
return
prompt = self.ai_image_input.get("1.0", tk.END).strip()
@@ -439,7 +445,7 @@ def _send_prompt(self):
)
def _set_requesting(self, flag: bool):
def _set_requesting(self: "PQAutomationApp", flag: bool):
self._ai_image_requesting = flag
try:
self.ai_image_send_btn.configure(state=tk.DISABLED if flag else tk.NORMAL)
@@ -465,7 +471,7 @@ def _set_requesting(self, flag: bool):
pass
def _on_request_done(self, record, exc, req_seq):
def _on_request_done(self: "PQAutomationApp", record, exc, req_seq):
# 旧请求回调(例如用户已点击停止后)直接忽略
if req_seq != getattr(self, "_ai_image_active_seq", 0):
return
@@ -493,7 +499,7 @@ def _on_request_done(self, record, exc, req_seq):
break
def _stop_request(self):
def _stop_request(self: "PQAutomationApp"):
"""停止当前生成任务(协作取消:屏蔽后续回调并恢复 UI"""
if not getattr(self, "_ai_image_requesting", False):
return
@@ -505,7 +511,7 @@ def _stop_request(self):
self.ai_image_status_var.set("已停止生成")
def _save_current(self):
def _save_current(self: "PQAutomationApp"):
rec = getattr(self, "ai_image_current", None)
if rec is None:
messagebox.showinfo("提示", "请先选择一张图片")
@@ -526,7 +532,7 @@ def _save_current(self):
messagebox.showerror("保存失败", str(exc))
def _delete_current(self):
def _delete_current(self: "PQAutomationApp"):
rec = getattr(self, "ai_image_current", None)
if rec is None:
messagebox.showinfo("提示", "请先选择一张图片")
@@ -537,7 +543,7 @@ def _delete_current(self):
reload_ai_image_list(self)
def _rename_current(self):
def _rename_current(self: "PQAutomationApp"):
"""弹窗让用户修改当前记录的展示标题(保存到侧车 ``title`` 字段,原始 prompt 不变)。"""
rec = getattr(self, "ai_image_current", None)
if rec is None:
@@ -580,7 +586,7 @@ def _rename_current(self):
# ---------------- 发送到 UCD ----------------
def _show_list_context_menu(self, event):
def _show_list_context_menu(self: "PQAutomationApp", event):
"""在图片列表上显示右键菜单,并根据状态启用/禁用项。"""
try:
row = self.ai_image_listbox.nearest(event.y)
@@ -619,7 +625,7 @@ def _show_list_context_menu(self, event):
self.ai_image_menu.grab_release()
def _send_to_ucd(self):
def _send_to_ucd(self: "PQAutomationApp"):
"""把当前选中的 AI 图片通过 UCD 发送到显示设备。"""
rec = getattr(self, "ai_image_current", None)
if rec is None:
@@ -730,3 +736,29 @@ def _build_ucd_resized_image(image_path: str, target_w: int, target_h: int) -> s
resized = img.convert("RGB").resize((target_w, target_h), Image.LANCZOS)
resized.save(out_path, format="PNG")
return out_path
class AIImagePanelMixin:
"""由 tools/refactor_to_mixins.py 自动生成。
把本模块的自由函数挂到 PQAutomationApp 上,便于 F12 跳转与类型推断。
"""
create_ai_image_panel = create_ai_image_panel
toggle_ai_image_panel = toggle_ai_image_panel
_get_app_base_dir = _get_app_base_dir
reload_ai_image_list = reload_ai_image_list
_on_list_select = _on_list_select
_select_record = _select_record
_redraw_preview = _redraw_preview
_start_new_session = _start_new_session
_session_id_for_row = _session_id_for_row
_switch_to_session = _switch_to_session
_update_request_progress = _update_request_progress
_send_prompt = _send_prompt
_set_requesting = _set_requesting
_on_request_done = _on_request_done
_stop_request = _stop_request
_save_current = _save_current
_delete_current = _delete_current
_rename_current = _rename_current
_show_list_context_menu = _show_list_context_menu
_send_to_ucd = _send_to_ucd