T-581 AI生成打开图片文件夹

This commit is contained in:
chengma
2026-07-10 10:46:52 +08:00
parent 68afe34a8d
commit 87fcda47e7
5 changed files with 366 additions and 3 deletions
+36
View File
@@ -0,0 +1,36 @@
"""Helpers for opening local folders from the GUI."""
from __future__ import annotations
import os
import subprocess
import sys
def open_in_file_manager(path: str) -> str:
"""Open an existing directory with the platform file manager.
Returns the absolute path that was opened. The helper never creates
directories; callers should present FileNotFoundError as a user-facing
warning.
"""
target = os.path.abspath(str(path or ""))
if not os.path.isdir(target):
raise FileNotFoundError(f"目录不存在:{target}")
if sys.platform.startswith("win"):
startfile = getattr(os, "startfile", None)
if startfile is None:
raise OSError("当前系统不支持打开文件夹")
startfile(target)
return target
command = ["open", target] if sys.platform == "darwin" else ["xdg-open", target]
subprocess.Popen(
command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=False,
)
return target
+86
View File
@@ -5,6 +5,7 @@ from __future__ import annotations
from PySide6.QtCore import QEvent, QRectF, QSize
from PySide6.QtGui import QColor, QPainter
from .. import file_manager
from ..models import GenerateTaskTableModel
from ..widgets import *
from ..workers import GenerateWorker as _RealGenerateWorker
@@ -882,6 +883,11 @@ class GenerateTab(QWidget):
for label, value in self.STATUS_FILTERS:
self.status_filter.addItem(label, value)
self.refresh_button = QPushButton("刷新")
self.open_image_dir_button = QPushButton("打开图片文件夹")
self.open_image_dir_button.setObjectName("openImageDirButton")
self.open_image_dir_button.setToolTip(
"选中某行→打开该账号图片文件夹;未选中→打开当前批次文件夹;全部批次→打开图片根目录"
)
filter_layout = QHBoxLayout()
filter_layout.addWidget(QLabel("批次"))
@@ -893,6 +899,7 @@ class GenerateTab(QWidget):
filter_layout.addWidget(QLabel("状态"))
filter_layout.addWidget(self.status_filter, 1)
filter_layout.addWidget(self.refresh_button)
filter_layout.addWidget(self.open_image_dir_button)
self.summary_label = QLabel("任务 0 条")
self.batch_progress_label = _build_batch_progress_overview("generateBatchProgressOverview")
@@ -973,6 +980,7 @@ class GenerateTab(QWidget):
self.item_filter.textChanged.connect(self.refresh_tasks)
self.status_filter.currentIndexChanged.connect(self.refresh_tasks)
self.refresh_button.clicked.connect(self.refresh_tasks)
self.open_image_dir_button.clicked.connect(self.open_image_directory)
self.save_title_button.clicked.connect(self.save_title_prompt)
self.insert_old_title_button.clicked.connect(self.insert_old_title_placeholder)
self.cover_template_combo.currentIndexChanged.connect(self.load_selected_cover_template)
@@ -1824,6 +1832,84 @@ class GenerateTab(QWidget):
failed=payload.get("failed", 0),
)
def open_image_directory(self):
target_dir, missing_message = self._resolve_image_directory_target()
if not target_dir:
message = missing_message or "无法定位图片文件夹"
QMessageBox.warning(self, "打开图片文件夹", message)
self._set_status(message, level="warning")
return
if not os.path.isdir(target_dir):
message = missing_message or "该批次/账号还没有图片"
QMessageBox.warning(self, "打开图片文件夹", message)
self._set_status(message, level="warning")
return
try:
opened_dir = file_manager.open_in_file_manager(target_dir)
except Exception as exc:
message = f"打开图片文件夹失败:{exc}"
QMessageBox.warning(self, "打开图片文件夹", message)
self._set_status(message, level="danger")
return
self._set_status(f"已打开图片文件夹:{opened_dir}", level="success")
def _resolve_image_directory_target(self):
image_root = appconfig.image_dir(self.config)
row = self._selected_row_for_image_directory()
if row is not None:
task = self.model.task_at(row)
if task is None:
return None, "没有选中可打开图片文件夹的任务"
existing_dir = self._existing_cover_parent_dir(task)
if existing_dir:
return existing_dir, "该账号还没有图片"
account = self._account_for_task(task)
if account is None:
return None, "选中任务没有匹配账号,无法定位图片文件夹"
target = os.path.dirname(
image_paths.task_image_path(
image_root,
task,
account=account,
suffix="new",
ext=".jpg",
)
)
return target, "该账号还没有图片"
selected_batch = self.batch_filter.currentData()
if selected_batch not in (None, "", "all"):
return os.path.abspath(os.path.join(image_root, str(selected_batch))), "该批次还没有图片"
return os.path.abspath(image_root), "图片根目录不存在,请先采集或生成图片"
def _selected_row_for_image_directory(self):
selection = self.task_table.selectionModel()
selected_rows = []
if selection is not None:
selected_rows = sorted({index.row() for index in selection.selectedRows()})
if not selected_rows:
return None
current = self.task_table.currentIndex()
if current.isValid() and current.row() in selected_rows:
return current.row()
return selected_rows[0]
def _existing_cover_parent_dir(self, task):
for attr in ("new_cover_path", "old_cover_path"):
value = str(getattr(task, attr, "") or "").strip()
if not value:
continue
path = os.path.abspath(value)
if os.path.isfile(path):
return os.path.dirname(path)
return None
def _account_for_task(self, task):
alias = str(getattr(task, "alias", "") or "").strip()
if not alias:
return None
return self.model.account_by_alias.get(alias)
def _selected_task(self):
index = self.task_table.currentIndex()
if index.isValid():