feat: show generate elapsed timings
This commit is contained in:
+119
-7
@@ -26,7 +26,7 @@ class GenerateTab(QWidget):
|
||||
"cover": "封面",
|
||||
"all": "标题和封面",
|
||||
}
|
||||
TABLE_COLUMN_WEIGHTS = (1.0, 0.5, 1.0, 1.0, 1.25, 1.25)
|
||||
TABLE_COLUMN_WEIGHTS = (1.0, 0.5, 1.8375, 1.8375, 0.4125, 0.4125)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -54,6 +54,10 @@ class GenerateTab(QWidget):
|
||||
self.current_cover_template = None
|
||||
self.generate_worker = None
|
||||
self.generate_thread = None
|
||||
self._title_elapsed_start = None
|
||||
self._cover_elapsed_start = None
|
||||
self._title_elapsed_seconds = 0
|
||||
self._cover_elapsed_seconds = 0
|
||||
|
||||
self.title_prompt_edit = QPlainTextEdit()
|
||||
self.title_prompt_edit.setObjectName("titlePromptEdit")
|
||||
@@ -110,8 +114,23 @@ class GenerateTab(QWidget):
|
||||
self.cover_progress_bar.setValue(0)
|
||||
self.failed_progress_label = QLabel("失败 0")
|
||||
self.failed_progress_label.setObjectName("generateFailedProgressLabel")
|
||||
self.failed_progress_label.setVisible(False)
|
||||
self.cmhub_balance_label = QLabel("cmhub余额:未获取")
|
||||
self.cmhub_balance_label.setObjectName("generateCmhubBalanceLabel")
|
||||
self.cmhub_balance_label.setVisible(False)
|
||||
self.title_elapsed_label = QLabel("生标题用时 0 秒")
|
||||
self.title_elapsed_label.setObjectName("generateTitleElapsedLabel")
|
||||
self.cover_elapsed_label = QLabel("生图用时 0 秒")
|
||||
self.cover_elapsed_label.setObjectName("generateCoverElapsedLabel")
|
||||
elapsed_width = max(
|
||||
self.title_elapsed_label.fontMetrics().horizontalAdvance("生标题用时 9999 秒"),
|
||||
self.cover_elapsed_label.fontMetrics().horizontalAdvance("生图用时 9999 秒"),
|
||||
) + 12
|
||||
self.title_elapsed_label.setFixedWidth(elapsed_width)
|
||||
self.cover_elapsed_label.setFixedWidth(elapsed_width)
|
||||
self._generate_elapsed_timer = QTimer(self)
|
||||
self._generate_elapsed_timer.setInterval(1000)
|
||||
self._generate_elapsed_timer.timeout.connect(self._refresh_elapsed_labels)
|
||||
|
||||
left_panel = QWidget()
|
||||
left_layout = QVBoxLayout(left_panel)
|
||||
@@ -209,11 +228,11 @@ class GenerateTab(QWidget):
|
||||
title_progress_layout = QHBoxLayout()
|
||||
title_progress_layout.addWidget(self.title_progress_label)
|
||||
title_progress_layout.addWidget(self.title_progress_bar, 1)
|
||||
title_progress_layout.addWidget(self.title_elapsed_label)
|
||||
cover_progress_layout = QHBoxLayout()
|
||||
cover_progress_layout.addWidget(self.cover_progress_label)
|
||||
cover_progress_layout.addWidget(self.cover_progress_bar, 1)
|
||||
cover_progress_layout.addWidget(self.failed_progress_label)
|
||||
cover_progress_layout.addWidget(self.cmhub_balance_label)
|
||||
cover_progress_layout.addWidget(self.cover_elapsed_label)
|
||||
progress_layout = QVBoxLayout()
|
||||
progress_layout.addLayout(title_progress_layout)
|
||||
progress_layout.addLayout(cover_progress_layout)
|
||||
@@ -258,6 +277,7 @@ class GenerateTab(QWidget):
|
||||
self.refresh_cover_templates()
|
||||
self.refresh_tasks()
|
||||
self._show_current_run_log_empty()
|
||||
self._reset_generation_elapsed()
|
||||
self._update_cmhub_balance_label({})
|
||||
|
||||
def resizeEvent(self, event):
|
||||
@@ -286,6 +306,92 @@ class GenerateTab(QWidget):
|
||||
f"本轮AI生成开始:任务 {len(tasks)} 条,生成封面:{cover_text}"
|
||||
)
|
||||
|
||||
def _reset_generation_elapsed(self):
|
||||
self._generate_elapsed_timer.stop()
|
||||
self._title_elapsed_start = None
|
||||
self._cover_elapsed_start = None
|
||||
self._title_elapsed_seconds = 0
|
||||
self._cover_elapsed_seconds = 0
|
||||
self._refresh_elapsed_labels()
|
||||
|
||||
def _start_generation_elapsed(self, title_total, cover_total):
|
||||
self._reset_generation_elapsed()
|
||||
now = time.monotonic()
|
||||
if int(title_total or 0) > 0:
|
||||
self._title_elapsed_start = now
|
||||
elif int(cover_total or 0) > 0:
|
||||
self._cover_elapsed_start = now
|
||||
self._refresh_elapsed_labels()
|
||||
self._update_elapsed_timer_state()
|
||||
|
||||
def _elapsed_seconds(self, start, frozen_seconds):
|
||||
if start is None:
|
||||
return max(0, int(frozen_seconds or 0))
|
||||
return max(0, int(time.monotonic() - start))
|
||||
|
||||
def _refresh_elapsed_labels(self):
|
||||
title_seconds = self._elapsed_seconds(
|
||||
self._title_elapsed_start,
|
||||
self._title_elapsed_seconds,
|
||||
)
|
||||
cover_seconds = self._elapsed_seconds(
|
||||
self._cover_elapsed_start,
|
||||
self._cover_elapsed_seconds,
|
||||
)
|
||||
self.title_elapsed_label.setText(f"生标题用时 {title_seconds} 秒")
|
||||
self.cover_elapsed_label.setText(f"生图用时 {cover_seconds} 秒")
|
||||
|
||||
def _update_elapsed_timer_state(self):
|
||||
if self._title_elapsed_start is not None or self._cover_elapsed_start is not None:
|
||||
if not self._generate_elapsed_timer.isActive():
|
||||
self._generate_elapsed_timer.start()
|
||||
return
|
||||
self._generate_elapsed_timer.stop()
|
||||
|
||||
def _freeze_title_elapsed(self):
|
||||
if self._title_elapsed_start is None:
|
||||
return
|
||||
self._title_elapsed_seconds = self._elapsed_seconds(
|
||||
self._title_elapsed_start,
|
||||
self._title_elapsed_seconds,
|
||||
)
|
||||
self._title_elapsed_start = None
|
||||
|
||||
def _freeze_cover_elapsed(self):
|
||||
if self._cover_elapsed_start is None:
|
||||
return
|
||||
self._cover_elapsed_seconds = self._elapsed_seconds(
|
||||
self._cover_elapsed_start,
|
||||
self._cover_elapsed_seconds,
|
||||
)
|
||||
self._cover_elapsed_start = None
|
||||
|
||||
def _sync_generation_elapsed(self, payload):
|
||||
title_total = max(0, int(payload.get("title_total", 0) or 0))
|
||||
title_done = max(0, int(payload.get("title_done", 0) or 0))
|
||||
cover_total = self._cover_total_for_progress(payload, int(payload.get("total", 0) or 0))
|
||||
cover_done = max(0, int(payload.get("cover_done", 0) or 0))
|
||||
if title_total > 0 and title_done >= title_total:
|
||||
self._freeze_title_elapsed()
|
||||
if (
|
||||
cover_total > 0
|
||||
and cover_done < cover_total
|
||||
and self._cover_elapsed_start is None
|
||||
and self._cover_elapsed_seconds == 0
|
||||
and (title_total == 0 or title_done >= title_total)
|
||||
):
|
||||
self._cover_elapsed_start = time.monotonic()
|
||||
if cover_total > 0 and cover_done >= cover_total:
|
||||
self._freeze_cover_elapsed()
|
||||
self._refresh_elapsed_labels()
|
||||
self._update_elapsed_timer_state()
|
||||
|
||||
def _finish_generation_elapsed(self, payload=None):
|
||||
self._freeze_title_elapsed()
|
||||
self._freeze_cover_elapsed()
|
||||
self._refresh_elapsed_labels()
|
||||
self._update_elapsed_timer_state()
|
||||
|
||||
def _on_generate_cover_toggled(self, checked):
|
||||
previous = bool(appconfig.ai_config(self.config).get("generate_cover", False))
|
||||
if self._save_generate_cover_setting(show_status=True):
|
||||
@@ -543,6 +649,10 @@ class GenerateTab(QWidget):
|
||||
worker.cancelled.connect(self._on_generate_cancelled)
|
||||
self._reset_generate_run_log(tasks, generate_cover)
|
||||
self._reset_cmhub_balance_label()
|
||||
self._start_generation_elapsed(
|
||||
component_totals["title_total"],
|
||||
component_totals["cover_total"] if generate_cover else 0,
|
||||
)
|
||||
thread = run_worker(worker, thread_name="GenerateWorker", start=False)
|
||||
thread.finished.connect(lambda: self._forget_generate_thread(thread))
|
||||
self.generate_worker = worker
|
||||
@@ -829,6 +939,7 @@ class GenerateTab(QWidget):
|
||||
|
||||
def _on_generate_progress(self, payload):
|
||||
self._update_generate_progress(payload)
|
||||
self._sync_generation_elapsed(payload)
|
||||
self._update_cmhub_balance_label(payload)
|
||||
self._set_status("生成进度:" + self._generate_progress_text(payload))
|
||||
|
||||
@@ -842,6 +953,7 @@ class GenerateTab(QWidget):
|
||||
self._set_generate_running(False)
|
||||
self.refresh_tasks()
|
||||
self._update_generate_progress(payload)
|
||||
self._finish_generation_elapsed(payload)
|
||||
self._update_cmhub_balance_label(payload)
|
||||
billing_error = payload.get("billing_error")
|
||||
if billing_error:
|
||||
@@ -856,6 +968,7 @@ class GenerateTab(QWidget):
|
||||
self._set_generate_running(False)
|
||||
self.refresh_tasks()
|
||||
self._update_generate_progress(payload)
|
||||
self._finish_generation_elapsed(payload)
|
||||
self._update_cmhub_balance_label(payload)
|
||||
billing_error = payload.get("billing_error")
|
||||
if billing_error:
|
||||
@@ -878,17 +991,16 @@ class GenerateTab(QWidget):
|
||||
self._set_progress_bar(self.cover_progress_bar, cover_done, cover_total)
|
||||
|
||||
def _reset_cmhub_balance_label(self):
|
||||
self.cmhub_balance_label.setVisible(False)
|
||||
if self._is_cmhub_backend():
|
||||
self.cmhub_balance_label.setVisible(True)
|
||||
self.cmhub_balance_label.setText("cmhub余额:生成后刷新")
|
||||
else:
|
||||
self.cmhub_balance_label.setVisible(False)
|
||||
self.cmhub_balance_label.setText("")
|
||||
|
||||
def _update_cmhub_balance_label(self, payload):
|
||||
self.cmhub_balance_label.setVisible(False)
|
||||
if not self._is_cmhub_backend():
|
||||
self.cmhub_balance_label.setVisible(False)
|
||||
return
|
||||
self.cmhub_balance_label.setVisible(True)
|
||||
balance = payload.get("points_balance") if isinstance(payload, dict) else None
|
||||
if balance is None:
|
||||
if not self.cmhub_balance_label.text():
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
try:
|
||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt
|
||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, QTimer
|
||||
from PySide6.QtGui import QColor, QIcon, QPainter, QPixmap
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractItemView,
|
||||
|
||||
Reference in New Issue
Block a user