feat: integrate Phase 1-4 components into main dashboard

- Performance tab: add PerformanceDashboard live stats widget
- Performance tab: add Benchmark button (opens BenchmarkDialog)
- Performance tab: add Export Report button (opens ExportReportDialog)
- Dongles tab: embed DeviceManagementPanel with 3s auto-refresh
- Fix pipeline_config type: analyze_pipeline_stages returns List not Dict

All integrations are guarded with try/except and AVAILABLE flags to
prevent import errors from breaking existing functionality.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
abin 2026-04-06 19:32:18 +08:00
parent 55040733fe
commit d2fdbf85ee

View File

@ -59,6 +59,25 @@ from core.nodes.exact_nodes import (
ExactPostprocessNode, ExactOutputNode, EXACT_NODE_TYPES
)
try:
from ui.components.performance_dashboard import PerformanceDashboard
PERFORMANCE_DASHBOARD_AVAILABLE = True
except ImportError:
PERFORMANCE_DASHBOARD_AVAILABLE = False
try:
from ui.components.device_management_panel import DeviceManagementPanel
from core.device.device_manager import DeviceManager
DEVICE_MANAGEMENT_AVAILABLE = True
except ImportError:
DEVICE_MANAGEMENT_AVAILABLE = False
try:
from ui.dialogs.export_report_dialog import ExportReportDialog
EXPORT_REPORT_AVAILABLE = True
except ImportError:
EXPORT_REPORT_AVAILABLE = False
# Import pipeline analysis functions
try:
from core.pipeline import get_stage_count, analyze_pipeline_stages, get_pipeline_summary
@ -158,6 +177,8 @@ class IntegratedPipelineDashboard(QMainWindow):
self.props_instructions = None
self.node_props_container = None
self.node_props_layout = None
self.device_manager = None
self.device_management_panel = None
self.fps_label = None
self.latency_label = None
self.memory_label = None
@ -895,7 +916,20 @@ class IntegratedPipelineDashboard(QMainWindow):
metrics_layout.addRow("Memory Usage:", self.memory_label)
layout.addWidget(metrics_group)
# Real-time performance monitor
perf_dashboard_group = QGroupBox("即時效能監控")
perf_dashboard_layout = QVBoxLayout(perf_dashboard_group)
if PERFORMANCE_DASHBOARD_AVAILABLE:
self.performance_dashboard = PerformanceDashboard()
else:
self.performance_dashboard = None
if self.performance_dashboard:
perf_dashboard_layout.addWidget(self.performance_dashboard)
else:
perf_dashboard_layout.addWidget(QLabel("PerformanceDashboard 不可用"))
layout.addWidget(perf_dashboard_group)
# Suggestions
suggestions_group = QGroupBox("Optimization Suggestions")
suggestions_layout = QVBoxLayout(suggestions_group)
@ -907,6 +941,26 @@ class IntegratedPipelineDashboard(QMainWindow):
layout.addWidget(suggestions_group)
# Benchmark section
benchmark_group = QGroupBox("效能 Benchmark")
benchmark_layout = QVBoxLayout(benchmark_group)
self.benchmark_button = QPushButton("執行 Benchmark")
self.benchmark_button.setToolTip("比較單 Dongle vs 多 Dongle 的效能差異")
self.benchmark_button.clicked.connect(self.open_benchmark_dialog)
benchmark_layout.addWidget(self.benchmark_button)
layout.addWidget(benchmark_group)
if EXPORT_REPORT_AVAILABLE:
export_group = QGroupBox("報告匯出")
export_layout = QVBoxLayout(export_group)
self.export_report_button = QPushButton("匯出效能報告PDF/CSV")
self.export_report_button.setToolTip("將 Benchmark 結果與歷史記錄匯出為 PDF 或 CSV")
self.export_report_button.clicked.connect(self.open_export_report_dialog)
export_layout.addWidget(self.export_report_button)
layout.addWidget(export_group)
# Deploy section
deploy_group = QGroupBox("Pipeline Deployment")
deploy_layout = QVBoxLayout(deploy_group)
@ -977,12 +1031,23 @@ class IntegratedPipelineDashboard(QMainWindow):
self.dongles_list.addItem("No dongles detected. Click 'Detect Dongles' to scan.")
layout.addWidget(self.dongles_list)
if DEVICE_MANAGEMENT_AVAILABLE:
try:
self.device_manager = DeviceManager()
self.device_management_panel = DeviceManagementPanel(self.device_manager)
self.device_management_panel.set_auto_refresh(3000)
layout.addWidget(self.device_management_panel)
except Exception as e:
err_label = QLabel(f"裝置管理面板初始化失敗:{e}")
err_label.setStyleSheet("color: #f38ba8; font-size: 11px;")
layout.addWidget(err_label)
layout.addStretch()
widget.setWidget(content)
widget.setWidgetResizable(True)
return widget
def setup_menu(self):
"""Setup the menu bar."""
menubar = self.menuBar()
@ -1925,7 +1990,58 @@ class IntegratedPipelineDashboard(QMainWindow):
suggestions.append("Pipeline configuration looks good for optimal performance.")
self.suggestions_text.setPlainText("\n".join(suggestions))
# Update PerformanceDashboard (if available)
if hasattr(self, 'performance_dashboard') and self.performance_dashboard:
self.performance_dashboard.update_stats({
"fps": float(estimated_fps),
"avg_latency_ms": float(estimated_latency),
"p95_latency_ms": float(estimated_latency * 1.5) # 估算 p95
})
def open_benchmark_dialog(self):
"""開啟 Benchmark 對話框。"""
try:
from ui.dialogs.benchmark_dialog import BenchmarkDialog
from core.pipeline import analyze_pipeline_stages
if not self.graph:
QMessageBox.warning(self, "無 Pipeline", "請先建立 Pipeline 再執行 Benchmark。")
return
stages = analyze_pipeline_stages(self.graph)
# analyze_pipeline_stages 回傳 List[PipelineStage]
pipeline_config = stages if stages else []
dialog = BenchmarkDialog(self, pipeline_config)
dialog.exec_()
except ImportError as e:
QMessageBox.warning(self, "功能未啟用", f"Benchmark 功能暫不可用:{e}")
def open_export_report_dialog(self):
"""開啟效能報告匯出對話框。"""
try:
from ui.dialogs.export_report_dialog import ExportReportDialog
from core.performance.benchmarker import PerformanceBenchmarker
from core.performance.history import PerformanceHistory
from core.device.device_manager import DeviceManager
benchmarker = getattr(self, '_benchmarker', None)
history = getattr(self, '_perf_history', None)
device_manager = getattr(self, 'device_manager', None)
dashboard = getattr(self, 'performance_dashboard', None)
dialog = ExportReportDialog(
parent=self,
benchmarker=benchmarker,
history=history,
device_manager=device_manager,
dashboard=dashboard,
)
dialog.exec_()
except Exception as e:
QMessageBox.warning(self, "匯出功能", f"無法開啟報告匯出:{e}")
def delete_selected_nodes(self):
"""Delete selected nodes from the graph."""
if not self.graph: