feat: implement fine-tune state and complete inter-panel signal wiring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 09:31:16 +08:00
co-authored by Claude Sonnet 4.6
parent aeb6b59ca1
commit 597da6744d
3 changed files with 106 additions and 16 deletions
+89 -9
View File
@@ -47,6 +47,10 @@ class MainWindow(QMainWindow):
# ------------------------------------------------------------------
def _build_ui(self):
# Fine-tune state: track which queue item is currently being edited
self._active_queue_item = None
self._loading_queue_item = False # suppress fine-tune marking during item load
root = QWidget()
root.setObjectName("root")
layout = QVBoxLayout(root)
@@ -246,20 +250,96 @@ class MainWindow(QMainWindow):
# ------------------------------------------------------------------
def _connect_signals(self):
"""Connect inter-panel signals needed for the queue workflow."""
# Asset lists → queue rebuilds automatically
# ── Asset lists ────────────────────────────────────────────────────
self.image_list_panel.garments_changed.connect(self.queue_panel.set_garments)
self.image_list_panel.prints_changed.connect(self.queue_panel.set_prints)
# Queue row selection → preview canvas
# Direct preview clicks → canvas (outside of queue flow)
self.image_list_panel.garment_preview_changed.connect(self._on_garment_preview)
self.image_list_panel.print_preview_changed.connect(self._on_print_preview)
# ── Queue ──────────────────────────────────────────────────────────
self.queue_panel.item_activated.connect(self._on_queue_item_activated)
# ── Canvas ↔ TransformPanel bidirectional sync ─────────────────────
# set_transform() on either side does NOT re-emit → no signal loop
self.image_canvas.transform_changed.connect(self.transform_panel.set_transform)
self.transform_panel.transform_changed.connect(self.image_canvas.set_transform)
# Both change paths feed fine-tune detection
self.image_canvas.transform_changed.connect(self._on_transform_changed)
self.transform_panel.transform_changed.connect(self._on_transform_changed)
# ── Template panel ─────────────────────────────────────────────────
# Template selection updates canvas, param panel, and queue template
self.template_panel.template_applied.connect(self.image_canvas.set_transform)
self.template_panel.template_applied.connect(self.transform_panel.set_transform)
self.template_panel.template_applied.connect(self.queue_panel.set_transform)
# ── Export panel secondary buttons → template panel ────────────────
self.export_panel.apply_as_template.connect(self.template_panel._save_as_template)
self.export_panel.reset_to_template.connect(self.template_panel._reset_to_template)
def _on_garment_preview(self, asset):
"""Load a garment from the asset list into the canvas for direct preview."""
self._active_queue_item = None # leave queue mode
if not asset:
self.export_panel.set_garment(None)
return
path = str(asset.path)
self.image_canvas.load_garment(path)
self.export_panel.set_garment(path)
# Tell template panel the garment dimensions so ratio→pixel conversion works
try:
from PIL import Image as _PilImage
with _PilImage.open(path) as img:
self.template_panel.set_garment_size(img.width, img.height)
except Exception:
pass
def _on_print_preview(self, asset):
"""Load a print from the asset list into the canvas for direct preview."""
self._active_queue_item = None
if not asset:
self.export_panel.set_print(None)
return
path = str(asset.path)
self.image_canvas.load_print(path)
self.export_panel.set_print(path)
def _on_queue_item_activated(self, item):
"""Load garment and print from a selected queue item into the canvas."""
self.image_canvas.load_garment(str(item.garment.path))
self.image_canvas.load_print(str(item.print_asset.path))
if item.transform:
self.image_canvas.set_transform(item.transform)
self.transform_panel.set_transform(item.transform)
"""Load a queue item into the canvas and arm fine-tune tracking."""
self._active_queue_item = item
self._loading_queue_item = True
try:
garment_path = str(item.garment.path)
print_path = str(item.print_asset.path)
self.image_canvas.load_garment(garment_path)
self.image_canvas.load_print(print_path)
self.export_panel.set_garment(garment_path)
self.export_panel.set_print(print_path)
# If the item already has a fine-tuned transform, restore it
if item.transform:
self.image_canvas.set_transform(item.transform)
self.transform_panel.set_transform(item.transform)
# Keep template panel garment size in sync
try:
from PIL import Image as _PilImage
with _PilImage.open(garment_path) as img:
self.template_panel.set_garment_size(img.width, img.height)
except Exception:
pass
finally:
self._loading_queue_item = False
def _on_transform_changed(self, state):
"""Route transform changes to panels and mark the active queue item fine-tuned."""
# Keep template panel and export panel up to date for save/export actions
self.template_panel.set_transform(state)
self.export_panel.set_transform(state)
# Mark the active queue item as fine-tuned (suppressed during item load)
if self._loading_queue_item or self._active_queue_item is None:
return
self.queue_panel.mark_item_fine_tuned(self._active_queue_item, state)
# ------------------------------------------------------------------
# Style (ref: docs/07-ui-design.md §10)
+10
View File
@@ -279,6 +279,16 @@ class QueuePanel(QWidget):
def set_export_options(self, options: ExportOptions):
self._export_options = options
def mark_item_fine_tuned(self, item: "QueueItem", state: TransformState):
"""Save a per-item transform and mark it as fine-tuned in the table."""
try:
row = self._model._items.index(item)
except ValueError:
return
item.transform = state
item.param_source = "已微调"
self._model.update_row(row)
# ── internal slots ───────────────────────────────────────────────────────
def _rebuild_queue(self):
+7 -7
View File
@@ -452,16 +452,16 @@
任务:
- [ ] 定义队列项微调状态
- [ ] 手动调整队列项后标记为 `已微调`
- [ ] 微调项保存独立 `TransformState`
- [ ] 批量导出时微调项使用自己的参数
- [ ] 未微调项使用模板参数
- [x] 定义队列项微调状态
- [x] 手动调整队列项后标记为 `已微调`
- [x] 微调项保存独立 `TransformState`
- [x] 批量导出时微调项使用自己的参数
- [x] 未微调项使用模板参数
验收:
- [ ] 已微调项不会被无提示覆盖
- [ ] 队列表格能显示 `模板` 和 `已微调`
- [x] 已微调项不会被无提示覆盖
- [x] 队列表格能显示 `模板` 和 `已微调`
## 15. 测试