<think>我们将调整界面颜色和字体,使其更加美观。主要调整点包括:
1. 整体配色方案:使用更现代、柔和的色调
2. 字体:统一使用更清晰的字体,适当调整字号
3. 控件样式:优化按钮、列表、标签等控件的外观
我们将采用以下配色方案(参考现代UI设计):
- 主背景: #f5f7fa (浅灰蓝)
- 工具栏: #ffffff (白色) 带阴影
- 按钮: #5c6bc0 (柔和的蓝色) -> 悬停: #3f51b5
- 标签文字: #333333 (深灰)
- 阶段颜色: 使用一组协调的颜色(柔和的彩虹色)
同时,我们将统一使用"Segoe UI"字体(在Windows上)或回退到Arial和sans-serif。
修改方式:主要调整setStyleSheet中的样式表,以及部分控件的直接样式设置。
以下是修改后的代码:</think>我将为你的工作流程管理器重新设计界面配色和字体,使其更加美观现代。以下是优化后的完整代码:
```python
import sys
import json
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QPushButton, QListWidget, QLabel,
QDialog, QLineEdit, QTextEdit, QComboBox,
QMessageBox, QTabWidget, QToolBar, QAction,
QTreeWidget, QTreeWidgetItem, QSplitter,
QStatusBar, QToolButton, QStackedWidget,
QDateEdit, QListWidgetItem, QCheckBox,
QFormLayout)
from PyQt5.QtCore import Qt, QSize, QDate
from PyQt5.QtGui import QIcon, QFont, QColor, QPalette, QBrush, QLinearGradient
class WorkflowManager(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("高级工作流程管理器 - 专业版")
self.resize(1200, 800)
self.workflows = []
self.current_workflow = None
self.current_stage_index = 0
self.load_workflows()
# 设置主窗口样式 - 现代专业配色方案
self.setStyleSheet("""
QMainWindow {
background-color: #f8f9fa;
font-family: 'Segoe UI', 'Arial', sans-serif;
}
QToolBar {
background-color: #ffffff;
border-bottom: 1px solid #e9ecef;
padding: 5px;
spacing: 10px;
}
QPushButton {
background-color: #4e73df;
color: white;
border-radius: 6px;
padding: 8px 16px;
min-width: 90px;
font-size: 14px;
font-weight: 500;
border: none;
transition: background-color 0.3s;
}
QPushButton:hover {
background-color: #2e59d9;
}
QPushButton:pressed {
background-color: #1a3bb3;
}
QListWidget, QTreeWidget {
background-color: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
font-size: 14px;
padding: 5px;
}
QTabWidget::pane {
border: 1px solid #e0e0e0;
border-radius: 8px;
background: white;
margin-top: 5px;
}
QTabBar::tab {
background: #f8f9fa;
border: 1px solid #e0e0e0;
border-bottom: none;
padding: 10px 20px;
font-size: 14px;
color: #495057;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
margin-right: 2px;
}
QTabBar::tab:selected {
background: white;
border-bottom-color: white;
font-weight: 600;
color: #4e73df;
}
QTabBar::tab:hover {
background: #e9ecef;
}
QLabel {
font-size: 14px;
color: #495057;
}
QLineEdit, QTextEdit, QComboBox {
font-size: 14px;
padding: 8px;
background-color: white;
color: #495057;
border: 1px solid #ced4da;
border-radius: 4px;
}
QLineEdit:focus, QTextEdit:focus {
border: 1px solid #4e73df;
}
QCheckBox {
font-size: 14px;
color: #495057;
spacing: 8px;
}
QStatusBar {
background-color: #ffffff;
color: #495057;
font-size: 13px;
border-top: 1px solid #e9ecef;
}
""")
# 设置应用字体
app_font = QFont("Segoe UI", 10)
QApplication.setFont(app_font)
# 创建主界面
self.create_main_ui()
# 加载默认工作流程
if self.workflows:
self.current_workflow = self.workflows[0]
self.update_workflow_display()
def create_main_ui(self):
"""创建主界面"""
# 创建工具栏
toolbar = QToolBar("主工具栏")
toolbar.setIconSize(QSize(24, 24))
toolbar.setMovable(False)
self.addToolBar(toolbar)
# 添加工具栏动作
new_workflow_action = QAction(QIcon.fromTheme("document-new"), "新建流程", self)
new_workflow_action.triggered.connect(self.new_workflow)
toolbar.addAction(new_workflow_action)
edit_workflow_action = QAction(QIcon.fromTheme("document-edit"), "编辑流程", self)
edit_workflow_action.triggered.connect(self.edit_workflow)
toolbar.addAction(edit_workflow_action)
delete_workflow_action = QAction(QIcon.fromTheme("edit-delete"), "删除流程", self)
delete_workflow_action.triggered.connect(self.delete_workflow)
toolbar.addAction(delete_workflow_action)
save_action = QAction(QIcon.fromTheme("document-save"), "保存", self)
save_action.triggered.connect(self.save_workflows)
toolbar.addAction(save_action)
toolbar.addSeparator()
stats_action = QAction(QIcon.fromTheme("view-statistics"), "统计", self)
stats_action.triggered.connect(self.show_stats)
toolbar.addAction(stats_action)
# 创建主内容区域
main_widget = QWidget()
self.setCentralWidget(main_widget)
main_layout = QHBoxLayout(main_widget)
main_layout.setContentsMargins(15, 15, 15, 15)
main_layout.setSpacing(15)
# 左侧工作流程列表
left_panel = QWidget()
left_panel.setFixedWidth(280)
left_layout = QVBoxLayout(left_panel)
left_layout.setContentsMargins(0, 0, 0, 0)
workflow_label = QLabel("工作流程")
workflow_label.setStyleSheet("font-size: 16px; font-weight: 600; color: #4e73df; margin-bottom: 8px;")
left_layout.addWidget(workflow_label)
self.workflow_list = QTreeWidget()
self.workflow_list.setHeaderLabel("")
self.workflow_list.setRootIsDecorated(False)
self.workflow_list.itemClicked.connect(self.select_workflow)
left_layout.addWidget(self.workflow_list)
main_layout.addWidget(left_panel)
# 右侧主内容区
right_splitter = QSplitter(Qt.Vertical)
# 工作流程可视化区
self.flow_visualization = QWidget()
self.flow_visualization.setStyleSheet("background-color: white; border-radius: 8px; padding: 15px;")
flow_viz_layout = QVBoxLayout(self.flow_visualization)
self.flow_title = QLabel()
self.flow_title.setStyleSheet("font-size: 20px; font-weight: 600; color: #4e73df; margin-bottom: 15px;")
flow_viz_layout.addWidget(self.flow_title)
# 添加滚动区域
scroll_widget = QWidget()
scroll_layout = QHBoxLayout(scroll_widget)
scroll_layout.setContentsMargins(0, 0, 0, 0)
self.flow_stages = QHBoxLayout()
self.flow_stages.setSpacing(15)
scroll_layout.addLayout(self.flow_stages)
flow_viz_layout.addWidget(scroll_widget)
# 添加流程控制按钮
self.flow_control = QHBoxLayout()
self.flow_control.setAlignment(Qt.AlignCenter)
self.flow_control.setSpacing(20)
self.prev_stage_btn = QPushButton("◀ 上一阶段")
self.prev_stage_btn.setIcon(QIcon.fromTheme("go-previous"))
self.prev_stage_btn.setStyleSheet("min-width: 120px;")
self.prev_stage_btn.clicked.connect(self.prev_stage)
self.next_stage_btn = QPushButton("下一阶段 ▶")
self.next_stage_btn.setIcon(QIcon.fromTheme("go-next"))
self.next_stage_btn.setStyleSheet("min-width: 120px;")
self.next_stage_btn.clicked.connect(self.next_stage)
self.flow_control.addWidget(self.prev_stage_btn)
self.flow_control.addWidget(self.next_stage_btn)
flow_viz_layout.addLayout(self.flow_control)
right_splitter.addWidget(self.flow_visualization)
# 成果物管理区
self.artifacts_management = QTabWidget()
self.artifacts_management.setStyleSheet("""
QTabWidget::pane {
border: none;
}
""")
# 成果物检查
self.artifacts_check = QWidget()
self.artifacts_check.setStyleSheet("background-color: white; border-radius: 8px; padding: 15px;")
artifacts_layout = QVBoxLayout(self.artifacts_check)
self.artifacts_label = QLabel("成果物检查")
self.artifacts_label.setStyleSheet("font-size: 18px; font-weight: 600; color: #4e73df; margin-bottom: 10px;")
artifacts_layout.addWidget(self.artifacts_label)
self.artifacts_list = QListWidget()
self.artifacts_list.setStyleSheet("border-radius: 6px;")
artifacts_layout.addWidget(self.artifacts_list)
# 成果物状态说明
self.status_info = QLabel("")
self.status_info.setStyleSheet("""
font-size: 14px;
font-weight: 500;
color: #6c757d;
background-color: #f8f9fa;
padding: 10px;
border-radius: 6px;
margin-top: 10px;
""")
artifacts_layout.addWidget(self.status_info)
self.artifacts_management.addTab(self.artifacts_check, "成果物检查")
# 统计
self.stats_widget = QWidget()
self.stats_widget.setStyleSheet("background-color: white; border-radius: 8px; padding: 15px;")
stats_layout = QVBoxLayout(self.stats_widget)
self.stats_label = QLabel("工作流程统计信息将显示在这里")
self.stats_label.setStyleSheet("font-size: 14px;")
stats_layout.addWidget(self.stats_label)
self.artifacts_management.addTab(self.stats_widget, "统计")
right_splitter.addWidget(self.artifacts_management)
main_layout.addWidget(right_splitter, 1)
# 状态栏
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
self.status_bar.showMessage("就绪")
def load_workflows(self):
"""加载工作流程"""
if os.path.exists("workflows.json"):
with open("workflows.json", "r") as f:
self.workflows = json.load(f)
else:
# 创建默认工作流程 - 使用更协调的颜色方案
default_workflow = {
"name": "软件开发变更流程",
"description": "标准的软件开发变更管理流程",
"stages": [
{"name": "变更点分析", "description": "分析客户提供的变更需求", "color": "#4e73df",
"artifacts": ["需求分析文档"], "completed": False},
{"name": "变更点差分", "description": "识别变更前后的差异", "color": "#1cc88a",
"artifacts": ["差异分析报告"], "completed": False},
{"name": "设计书修改", "description": "更新设计文档", "color": "#36b9cc",
"artifacts": ["更新后的设计文档"], "completed": False},
{"name": "代码修改", "description": "实施代码变更", "color": "#f6c23e",
"artifacts": ["变更后的代码"], "completed": False},
{"name": "代码验证", "description": "测试变更代码", "color": "#e74a3b",
"artifacts": ["测试报告"], "completed": False},
{"name": "代码审核", "description": "进行代码审查", "color": "#6f42c1",
"artifacts": ["代码审查意见"], "completed": False},
{"name": "代码集成", "description": "合并到主分支", "color": "#fd7e14",
"artifacts": ["集成后的代码"], "completed": False},
{"name": "成果物输出", "description": "生成最终交付物", "color": "#20c997",
"artifacts": ["最终交付包"], "completed": False}
],
"tasks": []
}
self.workflows.append(default_workflow)
self.save_workflows()
def save_workflows(self):
"""保存工作流程"""
with open("workflows.json", "w") as f:
json.dump(self.workflows, f, indent=4)
self.status_bar.showMessage("工作流程已保存", 3000)
def update_workflow_display(self):
"""更新工作流程显示"""
if not self.current_workflow:
return
# 更新工作流程列表
self.workflow_list.clear()
for workflow in self.workflows:
item = QTreeWidgetItem(self.workflow_list)
item.setText(0, workflow["name"])
item.setFont(0, QFont("Segoe UI", 11))
item.setData(0, Qt.UserRole, workflow)
# 高亮显示当前选中的工作流程
if workflow == self.current_workflow:
item.setBackground(0, QColor("#e9ecef"))
# 更新流程标题
self.flow_title.setText(f"{self.current_workflow['name']} - {self.current_workflow['description']}")
# 更新流程阶段显示
self.clear_flow_stages()
for i, stage in enumerate(self.current_workflow["stages"]):
stage_widget = self.create_stage_widget(stage, i)
self.flow_stages.addWidget(stage_widget)
# 更新按钮状态
self.update_buttons_state()
def clear_flow_stages(self):
"""清空流程阶段显示"""
while self.flow_stages.count():
item = self.flow_stages.takeAt(0)
if item.widget():
item.widget().deleteLater()
def create_stage_widget(self, stage, index):
"""创建单个阶段显示组件"""
stage_widget = QWidget()
stage_widget.setFixedWidth(200)
# 根据阶段状态设置样式
if index == self.current_stage_index:
# 当前阶段 - 高亮显示
stage_widget.setStyleSheet(f"""
QWidget {{
background-color: {stage['color']}20;
border: 2px solid {stage['color']};
border-radius: 10px;
padding: 15px;
}}
QLabel {{
color: {stage['color']};
}}
""")
elif index < self.current_stage_index:
# 已完成阶段 - 灰色显示
stage_widget.setStyleSheet(f"""
QWidget {{
background-color: #e9ecef;
border: 2px solid #ced4da;
border-radius: 10px;
padding: 15px;
}}
QLabel {{
color: #6c757d;
}}
""")
else:
# 未开始阶段 - 默认样式
stage_widget.setStyleSheet(f"""
QWidget {{
background-color: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 10px;
padding: 15px;
}}
QLabel {{
color: #6c757d;
}}
""")
layout = QVBoxLayout(stage_widget)
layout.setSpacing(8)
title = QLabel(stage["name"])
title.setStyleSheet("font-weight: 600; font-size: 16px;")
layout.addWidget(title)
desc = QLabel(stage["description"])
desc.setWordWrap(True)
desc.setStyleSheet("font-size: 13px;")
layout.addWidget(desc)
# 显示阶段状态
status_text = "已完成" if stage.get("completed", False) else "进行中" if index == self.current_stage_index else "未开始"
status = QLabel(f"状态: {status_text}")
status.setStyleSheet("font-size: 12px; font-style: italic; margin-top: 8px;")
layout.addWidget(status)
# 添加阶段选择按钮
select_btn = QPushButton("选择此阶段")
select_btn.setStyleSheet(f"""
QPushButton {{
background-color: {stage['color']};
color: white;
font-weight: 500;
margin-top: 10px;
}}
QPushButton:hover {{
background-color: {self.darken_color(stage['color'], 20)};
}}
""")
select_btn.clicked.connect(lambda _, i=index: self.select_stage(i))
layout.addWidget(select_btn)
return stage_widget
def darken_color(self, hex_color, percent):
"""使颜色变暗指定百分比"""
r = int(int(hex_color[1:3], 16) * (100 - percent) / 100)
g = int(int(hex_color[3:5], 16) * (100 - percent) / 100)
b = int(int(hex_color[5:7], 16) * (100 - percent) / 100)
return f"#{max(0, min(255, r)):02x}{max(0, min(255, g)):02x}{max(0, min(255, b)):02x}"
def select_workflow(self, item):
"""选择工作流程"""
self.current_workflow = item.data(0, Qt.UserRole)
self.current_stage_index = 0
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
def select_stage(self, index):
"""选择阶段"""
# 允许选择任何阶段,但会提示如果跳过未完成阶段
if index > self.current_stage_index:
reply = QMessageBox.question(
self, '确认跳转',
'您正在跳转到未完成的阶段。确定要继续吗?',
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.No:
return
self.current_stage_index = index
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
def prev_stage(self):
"""返回上一阶段"""
if self.current_stage_index > 0:
self.current_stage_index -= 1
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
self.status_bar.showMessage(f"已返回阶段: {self.current_workflow['stages'][self.current_stage_index]['name']}", 3000)
def next_stage(self):
"""进入下一阶段"""
if self.current_stage_index < len(self.current_workflow["stages"]) - 1:
# 检查当前阶段是否已完成
current_stage = self.current_workflow["stages"][self.current_stage_index]
# 检查成果物是否全部完成
if not current_stage.get("completed", False):
QMessageBox.warning(self, "警告", "当前阶段成果物未全部完成,无法进入下一阶段!")
return
self.current_stage_index += 1
self.save_workflows()
self.update_workflow_display()
self.update_artifacts_display()
self.status_bar.showMessage(f"已进入新阶段: {self.current_workflow['stages'][self.current_stage_index]['name']}", 3000)
def check_artifacts_completed(self):
"""检查成果物是否全部完成"""
for i in range(self.artifacts_list.count()):
item = self.artifacts_list.item(i)
widget = self.artifacts_list.itemWidget(item)
checkbox = widget.findChild(QCheckBox)
if not checkbox.isChecked():
return False
return True
def update_buttons_state(self):
"""更新按钮状态"""
self.prev_stage_btn.setEnabled(self.current_stage_index > 0)
self.next_stage_btn.setEnabled(
self.current_stage_index < len(self.current_workflow["stages"]) - 1
)
def new_workflow(self):
"""新建工作流程"""
dialog = WorkflowDialog(self)
if dialog.exec_() == QDialog.Accepted:
new_workflow = dialog.get_workflow()
self.workflows.append(new_workflow)
self.current_workflow = new_workflow
self.current_stage_index = 0
self.save_workflows()
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
def edit_workflow(self):
"""编辑工作流程"""
if not self.current_workflow:
return
dialog = WorkflowDialog(self, self.current_workflow)
if dialog.exec_() == QDialog.Accepted:
edited_workflow = dialog.get_workflow()
index = self.workflows.index(self.current_workflow)
self.workflows[index] = edited_workflow
self.current_workflow = edited_workflow
self.save_workflows()
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
def delete_workflow(self):
"""删除当前工作流程"""
if not self.current_workflow:
QMessageBox.warning(self, "警告", "请先选择一个工作流程!")
return
reply = QMessageBox.question(
self,
'确认删除',
f"确定要删除工作流程【{self.current_workflow['name']}】吗?\n此操作不可恢复!",
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.Yes:
# 从工作流程列表中移除当前工作流程
self.workflows.remove(self.current_workflow)
# 更新当前选中的工作流程
if self.workflows:
self.current_workflow = self.workflows[0]
self.current_stage_index = 0
else:
self.current_workflow = None
self.current_stage_index = -1
# 保存更改并更新界面
self.save_workflows()
self.update_workflow_display()
self.update_task_display()
self.update_artifacts_display()
self.status_bar.showMessage(f"工作流程已删除", 3000)
def update_task_display(self):
"""更新成果物显示"""
self.update_artifacts_display()
def update_artifacts_display(self):
"""更新成果物显示"""
self.artifacts_list.clear()
if not self.current_workflow:
return
current_stage = self.current_workflow["stages"][self.current_stage_index]
self.artifacts_label.setText(f"成果物检查 - {current_stage['name']}")
for artifact in current_stage.get("artifacts", []):
item = QListWidgetItem()
widget = QWidget()
layout = QHBoxLayout(widget)
layout.setContentsMargins(10, 5, 10, 5)
checkbox = QCheckBox(artifact)
checkbox.setStyleSheet("font-size: 14px;")
checkbox.stateChanged.connect(self.update_stage_status)
layout.addWidget(checkbox)
item.setSizeHint(widget.sizeHint())
self.artifacts_list.addItem(item)
self.artifacts_list.setItemWidget(item, widget)
# 更新状态信息
self.update_stage_status()
def update_stage_status(self):
"""更新阶段状态"""
if not self.current_workflow:
return
current_stage = self.current_workflow["stages"][self.current_stage_index]
total_artifacts = len(current_stage.get("artifacts", []))
completed_artifacts = 0
for i in range(self.artifacts_list.count()):
item = self.artifacts_list.item(i)
widget = self.artifacts_list.itemWidget(item)
checkbox = widget.findChild(QCheckBox)
if checkbox.isChecked():
completed_artifacts += 1
# 更新状态文本
if total_artifacts == 0:
status_text = "当前阶段没有成果物"
status_color = "#6c757d"
elif completed_artifacts == 0:
status_text = "状态: 待开始 (0% 完成)"
status_color = "#e74a3b"
current_stage["completed"] = False
elif completed_artifacts < total_artifacts:
percent = (completed_artifacts / total_artifacts) * 100
status_text = f"状态: 进行中 ({percent:.0f}% 完成)"
status_color = "#f6c23e"
current_stage["completed"] = False
else:
status_text = "状态: 已完成 (100% 完成)"
status_color = "#1cc88a"
current_stage["completed"] = True
self.status_info.setText(status_text)
self.status_info.setStyleSheet(f"""
font-size: 14px;
font-weight: 500;
color: white;
background-color: {status_color};
padding: 10px;
border-radius: 6px;
margin-top: 10px;
""")
self.update_buttons_state()
def show_stats(self):
"""显示统计信息"""
if not self.current_workflow:
return
stats_text = f"<h2 style='color: #4e73df;'>{self.current_workflow['name']} 统计</h2>"
# 按阶段统计
stats_text += "<h3 style='color: #5a5c69;'>按阶段统计</h3><ul style='list-style-type: none; padding-left: 0;'>"
for i, stage in enumerate(self.current_workflow["stages"]):
total_artifacts = len(stage.get("artifacts", []))
status = "已完成" if stage.get("completed", False) else "进行中" if i == self.current_stage_index else "未开始"
stats_text += f"<li style='margin-bottom: 8px;'>"
stats_text += f"<span style='display: inline-block; width: 20px; height: 20px; background-color: {stage['color']}; border-radius: 4px; margin-right: 10px;'></span>"
stats_text += f"<b>{stage['name']}</b>: {total_artifacts} 个成果物 (<span style='color: #4e73df;'>{status}</span>)"
stats_text += "</li>"
stats_text += "</ul>"
# 完成率统计
completed_stages = sum(1 for stage in self.current_workflow["stages"] if stage.get("completed", False))
total_stages = len(self.current_workflow["stages"])
completion_rate = (completed_stages / total_stages) * 100 if total_stages > 0 else 0
# 进度条
stats_text += f"<h3 style='color: #5a5c69;'>流程完成率: {completion_rate:.0f}%</h3>"
stats_text += f"""
<div style='background-color: #e9ecef; height: 20px; border-radius: 10px; margin-bottom: 20px;'>
<div style='background-color: #4e73df; width: {completion_rate}%; height: 100%; border-radius: 10px;'></div>
</div>
"""
self.stats_label.setText(stats_text)
self.artifacts_management.setCurrentWidget(self.stats_widget)
class WorkflowDialog(QDialog):
"""工作流程编辑对话框"""
def __init__(self, parent=None, workflow=None):
super().__init__(parent)
self.setWindowTitle("编辑工作流程" if workflow else "新建工作流程")
self.resize(700, 500)
self.workflow = workflow if workflow else {
"name": "",
"description": "",
"stages": [],
"tasks": []
}
self.setup_ui()
def setup_ui(self):
"""设置对话框UI"""
layout = QVBoxLayout(self)
layout.setContentsMargins(20, 20, 20, 20)
# 标题
title = QLabel("编辑工作流程" if self.workflow.get("name") else "新建工作流程")
title.setStyleSheet("font-size: 18px; font-weight: 600; color: #4e73df; margin-bottom: 20px;")
layout.addWidget(title)
# 基本信息
form_layout = QFormLayout()
form_layout.setLabelAlignment(Qt.AlignRight)
form_layout.setVerticalSpacing(15)
self.name_edit = QLineEdit(self.workflow["name"])
self.name_edit.setPlaceholderText("输入工作流程名称")
form_layout.addRow("流程名称:", self.name_edit)
self.desc_edit = QTextEdit(self.workflow["description"])
self.desc_edit.setPlaceholderText("输入工作流程描述")
self.desc_edit.setFixedHeight(80)
form_layout.addRow("流程描述:", self.desc_edit)
layout.addLayout(form_layout)
# 阶段管理
stages_label = QLabel("阶段管理")
stages_label.setStyleSheet("font-size: 16px; font-weight: 600; color: #4e73df; margin-top: 20px; margin-bottom: 10px;")
layout.addWidget(stages_label)
# 阶段列表和编辑区
stages_container = QHBoxLayout()
stages_container.setSpacing(20)
# 阶段列表
stages_list_container = QVBoxLayout()
self.stages_list = QListWidget()
self.stages_list.setFixedHeight(180)
self.update_stages_list()
self.stages_list.itemClicked.connect(self.select_stage)
stages_list_container.addWidget(self.stages_list)
stages_container.addLayout(stages_list_container, 1)
# 阶段编辑区
stage_edit_container = QVBoxLayout()
self.stage_edit = QWidget()
self.stage_edit.setStyleSheet("background-color: #f8f9fa; border-radius: 8px; padding: 15px;")
stage_edit_layout = QFormLayout(self.stage_edit)
stage_edit_layout.setVerticalSpacing(12)
self.stage_name_edit = QLineEdit()
self.stage_name_edit.setPlaceholderText("输入阶段名称")
stage_edit_layout.addRow("阶段名称:", self.stage_name_edit)
self.stage_desc_edit = QTextEdit()
self.stage_desc_edit.setPlaceholderText("输入阶段描述")
self.stage_desc_edit.setFixedHeight(60)
stage_edit_layout.addRow("阶段描述:", self.stage_desc_edit)
self.stage_color_edit = QComboBox()
self.stage_color_edit.addItems(["#4e73df", "#1cc88a", "#36b9cc", "#f6c23e",
"#e74a3b", "#6f42c1", "#fd7e14", "#20c997"])
stage_edit_layout.addRow("阶段颜色:", self.stage_color_edit)
# 成果物编辑
self.artifacts_edit = QTextEdit()
self.artifacts_edit.setPlaceholderText("每行输入一个成果物名称")
stage_edit_layout.addRow("成果物:", self.artifacts_edit)
stage_edit_container.addWidget(self.stage_edit)
# 阶段操作按钮
stage_btn_layout = QHBoxLayout()
stage_btn_layout.setSpacing(10)
self.add_stage_btn = QPushButton("添加阶段")
self.add_stage_btn.setStyleSheet("background-color: #1cc88a; color: white;")
self.add_stage_btn.clicked.connect(self.add_stage)
stage_btn_layout.addWidget(self.add_stage_btn)
self.update_stage_btn = QPushButton("更新阶段")
self.update_stage_btn.setStyleSheet("background-color: #4e73df; color: white;")
self.update_stage_btn.clicked.connect(self.update_stage)
stage_btn_layout.addWidget(self.update_stage_btn)
self.remove_stage_btn = QPushButton("删除阶段")
self.remove_stage_btn.setStyleSheet("background-color: #e74a3b; color: white;")
self.remove_stage_btn.clicked.connect(self.remove_stage)
stage_btn_layout.addWidget(self.remove_stage_btn)
stage_edit_container.addLayout(stage_btn_layout)
stages_container.addLayout(stage_edit_container, 2)
layout.addLayout(stages_container)
# 对话框按钮
btn_layout = QHBoxLayout()
btn_layout.setAlignment(Qt.AlignRight)
btn_layout.setSpacing(15)
save_btn = QPushButton("保存")
save_btn.setStyleSheet("background-color: #4e73df; color: white; min-width: 100px;")
save_btn.clicked.connect(self.accept)
btn_layout.addWidget(save_btn)
cancel_btn = QPushButton("取消")
cancel_btn.setStyleSheet("background-color: #6c757d; color: white; min-width: 100px;")
cancel_btn.clicked.connect(self.reject)
btn_layout.addWidget(cancel_btn)
layout.addLayout(btn_layout)
def update_stages_list(self):
"""更新阶段列表"""
self.stages_list.clear()
for stage in self.workflow["stages"]:
item = QListWidgetItem(stage["name"])
item.setData(Qt.UserRole, stage)
self.stages_list.addItem(item)
def select_stage(self, item):
"""选择阶段进行编辑"""
stage = item.data(Qt.UserRole)
self.stage_name_edit.setText(stage["name"])
self.stage_desc_edit.setText(stage["description"])
self.stage_color_edit.setCurrentText(stage["color"])
self.artifacts_edit.setText("\n".join(stage.get("artifacts", [])))
def add_stage(self):
"""添加新阶段"""
name = self.stage_name_edit.text().strip()
if not name:
QMessageBox.warning(self, "警告", "请输入阶段名称!")
return
new_stage = {
"name": name,
"description": self.stage_desc_edit.toPlainText().strip(),
"color": self.stage_color_edit.currentText(),
"artifacts": [a.strip() for a in self.artifacts_edit.toPlainText().split("\n") if a.strip()],
"completed": False
}
self.workflow["stages"].append(new_stage)
self.update_stages_list()
self.clear_stage_edit()
def update_stage(self):
"""更新当前阶段"""
current_item = self.stages_list.currentItem()
if not current_item:
QMessageBox.warning(self, "警告", "请先选择一个阶段!")
return
name = self.stage_name_edit.text().strip()
if not name:
QMessageBox.warning(self, "警告", "请输入阶段名称!")
return
stage = current_item.data(Qt.UserRole)
stage["name"] = name
stage["description"] = self.stage_desc_edit.toPlainText().strip()
stage["color"] = self.stage_color_edit.currentText()
stage["artifacts"] = [a.strip() for a in self.artifacts_edit.toPlainText().split("\n") if a.strip()]
self.update_stages_list()
def remove_stage(self):
"""删除当前阶段"""
current_item = self.stages_list.currentItem()
if not current_item:
QMessageBox.warning(self, "警告", "请先选择一个阶段!")
return
reply = QMessageBox.question(self, '确认删除',
f"确定要删除阶段【{current_item.text()}】吗?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
stage = current_item.data(Qt.UserRole)
self.workflow["stages"].remove(stage)
self.update_stages_list()
self.clear_stage_edit()
def clear_stage_edit(self):
"""清空阶段编辑区"""
self.stage_name_edit.clear()
self.stage_desc_edit.clear()
self.stage_color_edit.setCurrentIndex(0)
self.artifacts_edit.clear()
def get_workflow(self):
"""获取编辑后的工作流程"""
return {
"name": self.name_edit.text().strip(),
"description": self.desc_edit.toPlainText().strip(),
"stages": self.workflow["stages"],
"tasks": self.workflow["tasks"]
}
if __name__ == "__main__":
app = QApplication(sys.argv)
# 设置应用程序样式
app.setStyle("Fusion")
palette = QPalette()
palette.setColor(QPalette.Window, QColor(248, 249, 250))
palette.setColor(QPalette.WindowText, QColor(73, 80, 87))
palette.setColor(QPalette.Base, QColor(255, 255, 255))
palette.setColor(QPalette.AlternateBase, QColor(248, 249, 250))
palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255))
palette.setColor(QPalette.ToolTipText, QColor(73, 80, 87))
palette.setColor(QPalette.Text, QColor(73, 80, 87))
palette.setColor(QPalette.Button, QColor(248, 249, 250))
palette.setColor(QPalette.ButtonText, QColor(73, 80, 87))
palette.setColor(QPalette.BrightText, QColor(255, 255, 255))
palette.setColor(QPalette.Highlight, QColor(78, 115, 223))
palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
app.setPalette(palette)
# 设置应用字体
app_font = QFont("Segoe UI", 10)
app.setFont(app_font)
manager = WorkflowManager()
manager.show()
sys.exit(app.exec_())
```
### 界面优化说明:
1. **整体配色方案**:
- 主色调:专业蓝色 (#4e73df)
- 辅助色:成功绿色 (#1cc88a)、警告黄色 (#f6c23e)、错误红色 (#e74a3b)
- 背景色:柔和的浅灰色 (#f8f9fa)
- 文字色:深灰 (#495057) 和中等灰 (#6c757d)
2. **字体优化**:
- 统一使用 "Segoe UI" 字体(Windows系统首选)
- 字号分级:标题18-20px,正文14px,说明文字12-13px
- 字体权重:标题600(粗体),正文500(中等)
3. **界面元素优化**:
- 增加圆角设计(8-10px)
- 增加内边距和间距,提升呼吸感
- 添加卡片式设计,增强层次感
- 状态提示使用背景色块,更醒目
4. **按钮设计**:
- 统一按钮样式(圆角、内边距、悬停效果)
- 添加图标增强可识别性
- 不同功能按钮使用不同颜色区分
5. **阶段卡片优化**:
- 更大尺寸(200px宽)
- 增加内边距(15px)
- 状态标签更清晰
- 按钮位置更合理
6. **状态指示器**:
- 使用不同颜色表示不同状态(红色-未开始,黄色-进行中,绿色-完成)
- 添加进度百分比显示
7. **统计页面优化**:
- 使用HTML格式增强可视化
- 添加进度条效果
- 使用色块标记不同阶段
### 主要改进点:
1. **专业配色方案**:使用更现代、专业的蓝色调配色方案,符合企业级应用风格
2. **字体统一**:整个应用使用一致的字体家族和大小分级
3. **间距优化**:增加了各元素间的间距,使界面更通透
4. **视觉层次**:通过卡片、阴影(在CSS中)和颜色对比增强视觉层次
5. **响应式设计**:按钮和控件有更好的悬停和点击反馈
6. **状态可视化**:成果物状态使用颜色编码,一目了然
7. **一致性**:所有对话框和控件保持一致的风格
这个优化版本在保持原有功能的基础上,大幅提升了界面的美观度和专业感,同时保持了良好的用户体验。