4ce046be by shady

:bug: task_queue 三处 connect 补 Qt.QueuedConnection (等价 master a8d0cf0f)

master 上 a8d0cf0f 修过:worker_ref.{finished,error,progress}.connect
默认 DirectConnection,lambda 在 worker 线程同步执行,链路尽头动主线程
GUI (refresh_history / sidebar 刷新) → C++ access violation。
Windows 表现为 fatal exception,macOS 表现为静默 SIGKILL 闪退。

qml-poc 从 5f2a43f7 fork,没拿到这个修复。直接合回 master 会带着雷。
不 cherry-pick 原因:qml-poc 已把 'from image_generator import' 改成
'from core.generation import',cherry-pick a8d0cf0f 会冲突。
手工等价应用更干净。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2108d432
...@@ -209,17 +209,24 @@ class TaskQueueManager(QObject): ...@@ -209,17 +209,24 @@ class TaskQueueManager(QObject):
209 209
210 # 绑定信号;用 worker 局部引用捕获 finish_reason,避免后续 _current_worker 被替换 210 # 绑定信号;用 worker 局部引用捕获 finish_reason,避免后续 _current_worker 被替换
211 worker_ref = self._current_worker 211 worker_ref = self._current_worker
212 # 🔒 必须 QueuedConnection: worker_ref 是 QThread, finished/error/progress 从 worker 线程发出。
213 # lambda 没有 QObject thread affinity, 默认会被当成 DirectConnection 在 worker 线程同步执行,
214 # 链路尽头会动主线程 GUI (refresh_history / sidebar 刷新), C++ 层 access violation。
215 # Windows 表现为 fatal exception, macOS 表现为静默 SIGKILL 闪退。
212 worker_ref.finished.connect( 216 worker_ref.finished.connect(
213 lambda img_bytes, prompt, ref_imgs, ar, size, model: 217 lambda img_bytes, prompt, ref_imgs, ar, size, model:
214 self._on_task_completed(task_id, img_bytes, prompt, ref_imgs, ar, size, model, 218 self._on_task_completed(task_id, img_bytes, prompt, ref_imgs, ar, size, model,
215 getattr(worker_ref, 'finish_reason', None)) 219 getattr(worker_ref, 'finish_reason', None)),
220 Qt.QueuedConnection,
216 ) 221 )
217 worker_ref.error.connect( 222 worker_ref.error.connect(
218 lambda error: self._on_task_failed(task_id, error, 223 lambda error: self._on_task_failed(task_id, error,
219 getattr(worker_ref, 'finish_reason', None)) 224 getattr(worker_ref, 'finish_reason', None)),
225 Qt.QueuedConnection,
220 ) 226 )
221 worker_ref.progress.connect( 227 worker_ref.progress.connect(
222 lambda status: self.task_progress.emit(task_id, 0.5, status) 228 lambda status: self.task_progress.emit(task_id, 0.5, status),
229 Qt.QueuedConnection,
223 ) 230 )
224 231
225 self.task_started.emit(task_id) 232 self.task_started.emit(task_id)
......