reference_bridges.md 4.84 KB
name: QML 业务桥层 bridges/* API
description: 5 个 Bridge QObject 的 Property/Signal/Slot 形状(截至 2026-05-10)
type: reference
originSessionId: 21abab40-0d6c-449a-ae72-9ca03205f077

目录

bridges/
├── _icons.py       build_placeholder_icon
├── auth.py         AuthBridge      (db_config, audit_logger, last_user, saved_password_hash, config_path)
├── imagegen.py     ImageGenBridge  (TaskQueueManager, HistoryManager, AuthBridge, api_key, saved_prompts, config_path)
├── history.py      HistoryBridge   (HistoryManager)
├── taskqueue.py    TaskQueueBridge (TaskQueueManager)
└── jewelry.py      JewelryBridge   (JewelryLibraryManager)

main_qml.py contextProperty 名字auth / imageGen / history / taskQueue / jewelry / appState


AuthBridge

  • Property: loggedIn / currentUser / lastUser (constant) / hasSavedPassword (constant)
  • Slot:
    • login(user, pwd) → bool 明文密码
    • loginWithSavedPassword(user) → bool 用已存 hash("记住密码"路径,跳过 hash)
    • saveCredentials(pwd, rememberUser, rememberPwd) 写回 config.json(pwd="" 时保留旧 hash)
    • logout() / deviceName() → str
  • Signal: loggedInChanged / currentUserChanged / loginFailed(str)
  • 内部:登录成功同步拿 public IP(3 API 兜底 3s timeout)走 audit log_login

ImageGenBridge

  • Property: apiKey / busy / savedPrompts (list)
  • Slot:
    • submitTask(prompt, refs, aspect, size, mode) → task_id (task_type=IMAGE_GENERATION)
    • submitStyleTask(prompt, refs, aspect, size, mode) → task_id (task_type=STYLE_DESIGN)
    • cancelTask(task_id)
    • pasteFromClipboard() → list[str] 三层 fallback(hasUrls / mime raw bytes / imageData / clipboard.image)
    • macOS osascript 兜底(避免 Qt clipboard NSPasteboard→NSImage native crash)
    • normalizeFileUrls(urls) → list (内部走 _validate_image_file 校验扩展名 + ≤10MB + QPixmap)
    • validateImageFile(path) → {ok, reason} / validateImageFiles(paths) → list
    • saveFile(src, dest) → bool 下载图片
    • addSavedPrompt(p) / removeSavedPrompt(p) / toggleSavedPrompt(p) → bool (返回切换后的"已收藏"状态)
    • isSavedPrompt(p) → bool
  • Signal: taskSubmitted(taskId), taskCompleted(taskId, resultPath, prompt, model), taskFailed(taskId, error), taskProgress(taskId, progress, statusText), apiKeyChanged / busyChanged / savedPromptsChanged
  • 内部:on_completed 调 history.save_generation → 写 task.resultpath → emit taskCompleted

HistoryBridge

  • Property: model (HistoryListModel QAbstractListModel) / count
  • Slot:
    • refresh() 整体 reset / addNew(ts) 增量插顶
    • deleteItem(ts) 增量删 / clearAll() → bool rmtree+重建
    • getItem(ts) → dict 详情 / thumbnailPath(ts) → str 缩略图路径
    • revealInExplorer(path) Windows explorer /select, / macOS open -R / Linux xdg-open
    • copyToClipboard(text) → bool
    • redoToImageGen(ts) → emit redoRequested 让 ImageGenTab 回填 prompt+参考图+设置
  • Signal: itemAdded(ts) / itemRemoved(ts) / countChanged, redoRequested(payload) payload: {timestamp, prompt, referenceImages, aspectRatio, imageSize, mode}
  • HistoryListModel.roleNames: display / decoration / toolTip / timestamp(=UserRole)

TaskQueueBridge

  • Property: model (_TaskListModel) / pendingCount / runningCount
  • Slot: cancelTask(task_id), loadTask(task_id) → emit taskLoadRequested 回填到对应 tab
  • Signal: pendingCountChanged / runningCountChanged, taskLoadRequested(payload) payload: {taskId, type ("image_gen"|"style_design"), prompt, referenceImages, aspectRatio, imageSize, mode, resultPath (空字符串 if 未完成)}
  • _TaskListModel.roleNames: taskId / prompt / status / progress / statusText / elapsed
  • status 值: "pending" / "running" / "completed" / "failed"

JewelryBridge

  • Property: categories (list, 8 个类别)
  • Slot: getOptions(cat) → list, addItem(cat, val), removeItem(cat, val), resetCategory(cat), resetAll(), previewPrompt(formData) → str
  • Signal: libraryChanged(category)

主要 wiring 模式(QML 端):

  1. ImageGenTab 接 taskQueue.taskLoadRequested → type=image_gen 时回填 + 切 tab 0
  2. ImageGenTab 接 history.redoRequested → 回填(不带生成图)+ 切 tab 0
  3. StyleDesignerTab 接 taskQueue.taskLoadRequested → type=style_design 时回填 assembledPrompt + 切 tab 1
  4. ImageGenTab 接 imageGen.taskCompleted/Failed/Progress → 自己 myTaskIds 数组管理多任务

重要约束

  • bytes 永远不传 QML,写盘 → 传文件路径
  • Path 对象转 as_posix()(防 Windows 反斜杠在 QML "file:///" + path 拼接异常)
  • HistoryItem 等 dataclass 不直接暴露,用 getItem 转 dict
  • 异常都用 logger.exception(msg) 写完整 stack 到 logs/app.log