feat(gui): add two startup modes (new/open project)
This commit is contained in:
+146
-12
@@ -10,6 +10,7 @@ import os
|
||||
import threading
|
||||
import logging
|
||||
import configparser
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
# 设置环境
|
||||
@@ -63,16 +64,150 @@ class GUI(QMainWindow):
|
||||
|
||||
self.signaller = Signaller()
|
||||
self.worker_thread = None
|
||||
self._setup_ui()
|
||||
self.pipeline = None # 当前 Pipeline 实例
|
||||
self.project_config = None # 当前项目配置
|
||||
|
||||
# 连接信号
|
||||
self.signaller.log_signal.connect(self._append_log)
|
||||
self.signaller.finished_signal.connect(self._on_finished)
|
||||
|
||||
def _setup_ui(self):
|
||||
# 显示启动页
|
||||
self._setup_start_page()
|
||||
|
||||
def _clear_ui(self):
|
||||
"""清空当前 UI"""
|
||||
central = self.centralWidget()
|
||||
if central:
|
||||
central.deleteLater()
|
||||
|
||||
def _setup_start_page(self):
|
||||
"""启动页:新建项目 / 打开已有项目"""
|
||||
self.setWindowTitle("Piano Highlight Generator - GUI")
|
||||
self.setGeometry(100, 100, 500, 300)
|
||||
|
||||
self._clear_ui()
|
||||
central = QWidget()
|
||||
self.setCentralWidget(central)
|
||||
layout = QVBoxLayout(central)
|
||||
layout.setAlignment(Qt.AlignCenter)
|
||||
|
||||
# 标题
|
||||
title = QLabel("Piano Highlight Generator")
|
||||
title.setStyleSheet("font-size: 24px; font-weight: bold;")
|
||||
title.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(title)
|
||||
|
||||
layout.addSpacing(40)
|
||||
|
||||
# 按钮
|
||||
self.new_project_btn = QPushButton("新建项目")
|
||||
self.new_project_btn.setMinimumHeight(50)
|
||||
self.new_project_btn.clicked.connect(self._on_new_project)
|
||||
layout.addWidget(self.new_project_btn)
|
||||
|
||||
self.open_project_btn = QPushButton("打开已有项目")
|
||||
self.open_project_btn.setMinimumHeight(50)
|
||||
self.open_project_btn.clicked.connect(self._on_open_project)
|
||||
layout.addWidget(self.open_project_btn)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
def _on_new_project(self):
|
||||
"""新建项目:切换到文件选择界面"""
|
||||
self._setup_new_project_ui()
|
||||
|
||||
def _on_open_project(self):
|
||||
"""打开已有项目"""
|
||||
dir_path = QFileDialog.getExistingDirectory(self, "选择项目目录")
|
||||
if not dir_path:
|
||||
return
|
||||
self.load_project(dir_path)
|
||||
|
||||
def load_project(self, output_dir):
|
||||
"""
|
||||
加载已有项目,加载 generated_config.yaml,显示 clip 列表
|
||||
"""
|
||||
config_path = os.path.join(output_dir, 'generated_config.yaml')
|
||||
if not os.path.exists(config_path):
|
||||
QMessageBox.critical(self, "错误", f"不是有效的项目目录:\n{config_path}")
|
||||
return
|
||||
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
self.project_config = yaml.safe_load(f)
|
||||
|
||||
self.project_config['output_dir'] = output_dir
|
||||
|
||||
# 初始化 Pipeline
|
||||
self.pipeline = Pipeline(self.project_config)
|
||||
|
||||
# 显示项目信息(Task 9 完成后替换为完整编辑界面)
|
||||
self._show_project_info()
|
||||
|
||||
def _show_project_info(self):
|
||||
"""显示项目基本信息(临时,过渡用)"""
|
||||
self.setWindowTitle("项目信息 - Piano Highlight Generator")
|
||||
self.setGeometry(100, 100, 600, 400)
|
||||
|
||||
self._clear_ui()
|
||||
central = QWidget()
|
||||
self.setCentralWidget(central)
|
||||
layout = QVBoxLayout(central)
|
||||
|
||||
# 项目路径
|
||||
layout.addWidget(QLabel(f"<b>项目目录:</b> {self.project_config.get('output_dir', 'N/A')}"))
|
||||
|
||||
# 视频源
|
||||
video_src = self.project_config.get('video_src', 'N/A')
|
||||
layout.addWidget(QLabel(f"<b>视频:</b> {video_src}"))
|
||||
|
||||
# PPT 源
|
||||
ppt_src = self.project_config.get('ppt_src', 'N/A')
|
||||
layout.addWidget(QLabel(f"<b>PPT:</b> {ppt_src}"))
|
||||
|
||||
# Clips 数量
|
||||
clips = self.project_config.get('clips', [])
|
||||
layout.addWidget(QLabel(f"<b>Clips 数量:</b> {len(clips)}"))
|
||||
|
||||
# Clips 列表
|
||||
if clips:
|
||||
list_label = QLabel("<b>Clips 列表:</b>")
|
||||
layout.addWidget(list_label)
|
||||
for i, clip in enumerate(clips[:10]): # 只显示前10个
|
||||
title = clip.get('title', clip.get('content', 'N/A'))[:50]
|
||||
start = clip.get('start_time', 'N/A')
|
||||
end = clip.get('end_time', 'N/A')
|
||||
layout.addWidget(QLabel(f" {i+1}. [{start}-{end}] {title}"))
|
||||
if len(clips) > 10:
|
||||
layout.addWidget(QLabel(f" ... 还有 {len(clips) - 10} 个"))
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# 按钮区
|
||||
btn_layout = QHBoxLayout()
|
||||
self.edit_btn = QPushButton("进入编辑模式")
|
||||
self.edit_btn.clicked.connect(self._setup_edit_ui) # Task 9 实现
|
||||
back_btn = QPushButton("返回")
|
||||
back_btn.clicked.connect(self._setup_start_page)
|
||||
btn_layout.addWidget(self.edit_btn)
|
||||
btn_layout.addWidget(back_btn)
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
def _setup_edit_ui(self):
|
||||
"""
|
||||
编辑界面(Task 9 实现)
|
||||
目前显示 TODO 提示
|
||||
"""
|
||||
QMessageBox.information(
|
||||
self, "提示",
|
||||
"编辑模式将在 Task 9 中实现\n目前可以手动编辑 generated_config.yaml 后重新运行"
|
||||
)
|
||||
|
||||
def _setup_new_project_ui(self):
|
||||
"""新建项目的文件选择界面"""
|
||||
self.setWindowTitle("新建项目 - Piano Highlight Generator")
|
||||
self.setGeometry(100, 100, 700, 500)
|
||||
|
||||
self._clear_ui()
|
||||
central = QWidget()
|
||||
self.setCentralWidget(central)
|
||||
layout = QVBoxLayout(central)
|
||||
@@ -124,12 +259,11 @@ class GUI(QMainWindow):
|
||||
# === 按钮区 ===
|
||||
btn_layout = QHBoxLayout()
|
||||
self.start_btn = QPushButton("开始处理")
|
||||
self.start_btn.clicked.connect(self._on_start)
|
||||
self.clear_btn = QPushButton("清空日志")
|
||||
self.clear_btn.clicked.connect(lambda: self.log_area.clear())
|
||||
self.start_btn.clicked.connect(self._on_start_new)
|
||||
self.back_btn = QPushButton("返回")
|
||||
self.back_btn.clicked.connect(self._setup_start_page)
|
||||
btn_layout.addWidget(self.start_btn)
|
||||
btn_layout.addWidget(self.clear_btn)
|
||||
btn_layout.addStretch()
|
||||
btn_layout.addWidget(self.back_btn)
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
def _select_file(self, edit, filter_str):
|
||||
@@ -156,8 +290,8 @@ class GUI(QMainWindow):
|
||||
else:
|
||||
QMessageBox.critical(self, "错误", message)
|
||||
|
||||
def _on_start(self):
|
||||
# 收集参数
|
||||
def _on_start_new(self):
|
||||
"""开始新建项目流程"""
|
||||
video_path = self.video_edit.text().strip()
|
||||
ppt_path = self.ppt_edit.text().strip()
|
||||
output_dir = self.output_edit.text().strip()
|
||||
@@ -182,12 +316,13 @@ class GUI(QMainWindow):
|
||||
|
||||
# 后台线程执行
|
||||
self.worker_thread = threading.Thread(
|
||||
target=self._worker,
|
||||
target=self._worker_new,
|
||||
args=(video_path, ppt_path, output_dir, api_key, api_host)
|
||||
)
|
||||
self.worker_thread.start()
|
||||
|
||||
def _worker(self, video_path, ppt_path, output_dir, api_key, api_host):
|
||||
def _worker_new(self, video_path, ppt_path, output_dir, api_key, api_host):
|
||||
"""新建项目的工作线程"""
|
||||
try:
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
@@ -217,7 +352,6 @@ class GUI(QMainWindow):
|
||||
|
||||
# 保存配置
|
||||
config_path = os.path.join(output_dir, 'generated_config.yaml')
|
||||
import yaml
|
||||
with open(config_path, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(config, f, allow_unicode=True, default_flow_style=False)
|
||||
self.signaller.log_signal.emit(f"配置已保存: {config_path}")
|
||||
|
||||
Reference in New Issue
Block a user