AIDeveloper-PC/gui_ai_developer/dialogs/pipeline_dialog.py

301 lines
9.8 KiB
Python
Raw Normal View History

2026-01-31 09:32:00 +00:00
"""
流水线执行对话框
"""
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QTextEdit, QPushButton, QProgressBar, QFrame, QMessageBox
)
from PyQt5.QtCore import Qt, QTimer
from datetime import datetime
class PipelineDialog(QDialog):
"""流水线执行对话框"""
def __init__(self, project, parent=None):
"""
初始化对话框
Args:
project: 项目对象
parent: 父窗口
"""
super().__init__(parent)
self.project = project
self.current_step = 0
self.timer = None
self._setup_ui()
def _setup_ui(self):
"""设置UI"""
self.setWindowTitle(f"流水线 - {self.project.name}")
self.resize(1000, 600)
layout = QVBoxLayout(self)
layout.setSpacing(15)
# 标题
title_label = QLabel(f"<h2>🚀 项目流水线 - {self.project.name}</h2>")
layout.addWidget(title_label)
# 流水线步骤
steps_layout = QHBoxLayout()
steps_layout.setSpacing(10)
self.step_widgets = []
steps = [
("🔍", "静态扫描", "SonarQube"),
("🔨", "编译构建", "Maven"),
("📦", "打包", "JAR"),
("🚀", "部署", "测试环境"),
("", "验证测试", "JUnit")
]
for icon, name, tool in steps:
step_widget = self._create_step_widget(icon, name, tool)
self.step_widgets.append(step_widget)
steps_layout.addWidget(step_widget)
layout.addLayout(steps_layout)
# 日志输出区域
log_label = QLabel("<b>执行日志:</b>")
layout.addWidget(log_label)
self.log_text = QTextEdit()
self.log_text.setReadOnly(True)
self.log_text.setStyleSheet("""
QTextEdit {
background: #1e293b;
color: #10b981;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 12px;
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 8px;
padding: 10px;
}
""")
layout.addWidget(self.log_text)
# 总体进度条
self.progress = QProgressBar()
self.progress.setTextVisible(True)
self.progress.setFormat("%p%")
layout.addWidget(self.progress)
# 按钮区域
button_layout = QHBoxLayout()
button_layout.addStretch()
self.start_btn = QPushButton("▶ 启动流水线")
self.start_btn.setStyleSheet("""
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #10b981, stop:1 #059669);
}
""")
self.start_btn.setMinimumWidth(120)
self.start_btn.clicked.connect(self._start_pipeline)
button_layout.addWidget(self.start_btn)
self.stop_btn = QPushButton("⏹ 停止")
self.stop_btn.setStyleSheet("""
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #ef4444, stop:1 #dc2626);
}
""")
self.stop_btn.setMinimumWidth(120)
self.stop_btn.setEnabled(False)
self.stop_btn.clicked.connect(self._stop_pipeline)
button_layout.addWidget(self.stop_btn)
close_btn = QPushButton("关闭")
close_btn.setMinimumWidth(120)
close_btn.clicked.connect(self.accept)
button_layout.addWidget(close_btn)
layout.addLayout(button_layout)
def _create_step_widget(self, icon: str, name: str, tool: str) -> QFrame:
"""创建步骤组件"""
widget = QFrame()
widget.setFrameShape(QFrame.StyledPanel)
widget.setStyleSheet("""
QFrame {
background: rgba(51, 65, 85, 0.4);
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 8px;
padding: 15px;
}
""")
layout = QVBoxLayout(widget)
layout.setAlignment(Qt.AlignCenter)
layout.setSpacing(8)
# 图标
icon_label = QLabel(icon)
icon_label.setStyleSheet("font-size: 36px;")
icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label)
# 步骤名称
name_label = QLabel(name)
name_label.setStyleSheet("""
font-weight: bold;
font-size: 14px;
color: #e0e6ed;
""")
name_label.setAlignment(Qt.AlignCenter)
layout.addWidget(name_label)
# 工具名称
tool_label = QLabel(tool)
tool_label.setStyleSheet("""
color: #94a3b8;
font-size: 11px;
""")
tool_label.setAlignment(Qt.AlignCenter)
layout.addWidget(tool_label)
# 状态标签
status_label = QLabel("就绪")
status_label.setObjectName("status_label")
status_label.setStyleSheet("""
color: #94a3b8;
font-size: 12px;
""")
status_label.setAlignment(Qt.AlignCenter)
layout.addWidget(status_label)
return widget
def _start_pipeline(self):
"""启动流水线"""
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.current_step = 0
self.progress.setValue(0)
self.log_text.clear()
self._add_log("[INFO] ========================================")
self._add_log(f"[INFO] 流水线启动 - 项目: {self.project.name}")
self._add_log("[INFO] ========================================")
# 使用定时器模拟流水线执行
self.timer = QTimer()
self.timer.timeout.connect(self._update_pipeline)
self.timer.start(1500) # 每1.5秒执行一步
def _update_pipeline(self):
"""更新流水线状态"""
if self.current_step < len(self.step_widgets):
widget = self.step_widgets[self.current_step]
# 更新为进行中状态
widget.setStyleSheet("""
QFrame {
background: rgba(59, 130, 246, 0.3);
border: 2px solid #3b82f6;
border-radius: 8px;
padding: 15px;
}
""")
# 更新状态标签
status_label = widget.findChild(QLabel, "status_label")
if status_label:
status_label.setText("进行中...")
status_label.setStyleSheet("""
color: #3b82f6;
font-size: 12px;
font-weight: bold;
""")
# 添加日志
step_names = ["静态扫描", "编译构建", "打包", "部署", "验证测试"]
self._add_log(f"[INFO] 开始执行: {step_names[self.current_step]}")
self._add_log(f"[INFO] 步骤 {self.current_step + 1}/{len(self.step_widgets)}")
# 更新进度条
progress_value = int((self.current_step + 1) / len(self.step_widgets) * 100)
self.progress.setValue(progress_value)
# 延迟标记为完成
QTimer.singleShot(1000, lambda: self._complete_step(self.current_step))
self.current_step += 1
else:
self.timer.stop()
self._finish_pipeline()
def _complete_step(self, step_index: int):
"""完成步骤"""
if step_index < len(self.step_widgets):
widget = self.step_widgets[step_index]
# 更新为完成状态
widget.setStyleSheet("""
QFrame {
background: rgba(16, 185, 129, 0.2);
border: 2px solid #10b981;
border-radius: 8px;
padding: 15px;
}
""")
# 更新状态标签
status_label = widget.findChild(QLabel, "status_label")
if status_label:
status_label.setText("✓ 完成")
status_label.setStyleSheet("""
color: #10b981;
font-size: 12px;
font-weight: bold;
""")
# 添加完成日志
step_names = ["静态扫描", "编译构建", "打包", "部署", "验证测试"]
self._add_log(f"[SUCCESS] {step_names[step_index]} 完成")
self._add_log("")
def _finish_pipeline(self):
"""完成流水线"""
self._add_log("[INFO] ========================================")
self._add_log("[SUCCESS] 流水线执行完成!")
self._add_log(f"[INFO] 项目: {self.project.name}")
self._add_log("[INFO] 所有步骤已成功执行")
self._add_log("[INFO] ========================================")
self.start_btn.setEnabled(True)
self.stop_btn.setEnabled(False)
QMessageBox.information(
self,
"完成",
f"流水线执行完成!\n\n项目: {self.project.name}\n所有步骤已成功执行。"
)
def _stop_pipeline(self):
"""停止流水线"""
if self.timer:
self.timer.stop()
self._add_log("")
self._add_log("[WARNING] ========================================")
self._add_log("[WARNING] 流水线已被用户停止")
self._add_log("[WARNING] ========================================")
self.start_btn.setEnabled(True)
self.stop_btn.setEnabled(False)
def _add_log(self, message: str):
"""添加日志"""
timestamp = datetime.now().strftime("%H:%M:%S")
self.log_text.append(f"[{timestamp}] {message}")
# 自动滚动到底部
scrollbar = self.log_text.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())