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:
+86
-6
@@ -47,6 +47,10 @@ class MainWindow(QMainWindow):
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def _build_ui(self):
|
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 = QWidget()
|
||||||
root.setObjectName("root")
|
root.setObjectName("root")
|
||||||
layout = QVBoxLayout(root)
|
layout = QVBoxLayout(root)
|
||||||
@@ -246,20 +250,96 @@ class MainWindow(QMainWindow):
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def _connect_signals(self):
|
def _connect_signals(self):
|
||||||
"""Connect inter-panel signals needed for the queue workflow."""
|
# ── Asset lists ────────────────────────────────────────────────────
|
||||||
# Asset lists → queue rebuilds automatically
|
|
||||||
self.image_list_panel.garments_changed.connect(self.queue_panel.set_garments)
|
self.image_list_panel.garments_changed.connect(self.queue_panel.set_garments)
|
||||||
self.image_list_panel.prints_changed.connect(self.queue_panel.set_prints)
|
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)
|
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):
|
def _on_queue_item_activated(self, item):
|
||||||
"""Load garment and print from a selected queue item into the canvas."""
|
"""Load a queue item into the canvas and arm fine-tune tracking."""
|
||||||
self.image_canvas.load_garment(str(item.garment.path))
|
self._active_queue_item = item
|
||||||
self.image_canvas.load_print(str(item.print_asset.path))
|
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:
|
if item.transform:
|
||||||
self.image_canvas.set_transform(item.transform)
|
self.image_canvas.set_transform(item.transform)
|
||||||
self.transform_panel.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)
|
# Style (ref: docs/07-ui-design.md §10)
|
||||||
|
|||||||
@@ -279,6 +279,16 @@ class QueuePanel(QWidget):
|
|||||||
def set_export_options(self, options: ExportOptions):
|
def set_export_options(self, options: ExportOptions):
|
||||||
self._export_options = options
|
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 ───────────────────────────────────────────────────────
|
# ── internal slots ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
def _rebuild_queue(self):
|
def _rebuild_queue(self):
|
||||||
|
|||||||
@@ -452,16 +452,16 @@
|
|||||||
|
|
||||||
任务:
|
任务:
|
||||||
|
|
||||||
- [ ] 定义队列项微调状态
|
- [x] 定义队列项微调状态
|
||||||
- [ ] 手动调整队列项后标记为 `已微调`
|
- [x] 手动调整队列项后标记为 `已微调`
|
||||||
- [ ] 微调项保存独立 `TransformState`
|
- [x] 微调项保存独立 `TransformState`
|
||||||
- [ ] 批量导出时微调项使用自己的参数
|
- [x] 批量导出时微调项使用自己的参数
|
||||||
- [ ] 未微调项使用模板参数
|
- [x] 未微调项使用模板参数
|
||||||
|
|
||||||
验收:
|
验收:
|
||||||
|
|
||||||
- [ ] 已微调项不会被无提示覆盖
|
- [x] 已微调项不会被无提示覆盖
|
||||||
- [ ] 队列表格能显示 `模板` 和 `已微调`
|
- [x] 队列表格能显示 `模板` 和 `已微调`
|
||||||
|
|
||||||
## 15. 测试
|
## 15. 测试
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user