T-581 AI生成打开图片文件夹
This commit is contained in:
@@ -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
|
||||
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user