# -*- coding: utf-8 -*- """应用程序设置对话框""" from pathlib import Path from PySide6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox, QLabel, QLineEdit, QPushButton, QFileDialog, QMessageBox, QDialogButtonBox ) from PySide6.QtCore import Qt from ..utils.app_settings import app_settings class SettingsDialog(QDialog): """设置对话框""" def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("应用程序设置") self.setMinimumWidth(600) self._init_ui() self._load_settings() def _init_ui(self): layout = QVBoxLayout(self) # ETL 项目路径 project_group = QGroupBox("ETL 项目配置") project_layout = QGridLayout(project_group) project_layout.addWidget(QLabel("ETL 项目路径:"), 0, 0) self.project_path_edit = QLineEdit() self.project_path_edit.setPlaceholderText("例: etl_billiards") project_layout.addWidget(self.project_path_edit, 0, 1) browse_project_btn = QPushButton("浏览...") browse_project_btn.clicked.connect(self._browse_project_path) project_layout.addWidget(browse_project_btn, 0, 2) project_layout.addWidget(QLabel(".env 文件路径:"), 1, 0) self.env_path_edit = QLineEdit() self.env_path_edit.setPlaceholderText("例: etl_billiards/.env") project_layout.addWidget(self.env_path_edit, 1, 1) browse_env_btn = QPushButton("浏览...") browse_env_btn.clicked.connect(self._browse_env_path) project_layout.addWidget(browse_env_btn, 1, 2) # 验证按钮 validate_btn = QPushButton("验证配置") validate_btn.clicked.connect(self._validate_config) project_layout.addWidget(validate_btn, 2, 1) # 验证结果 self.validation_label = QLabel() self.validation_label.setWordWrap(True) project_layout.addWidget(self.validation_label, 3, 0, 1, 3) layout.addWidget(project_group) # 说明 note = QLabel( "说明:\n" "• ETL 项目路径:包含 cli/main.py 的目录\n" "• .env 文件路径:环境变量配置文件\n" "• 配置后才能正常执行 ETL 任务" ) note.setProperty("subheading", True) note.setWordWrap(True) layout.addWidget(note) layout.addStretch() # 按钮 btn_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) btn_box.accepted.connect(self._save_and_accept) btn_box.rejected.connect(self.reject) layout.addWidget(btn_box) def _load_settings(self): """加载设置""" self.project_path_edit.setText(app_settings.etl_project_path) self.env_path_edit.setText(app_settings.env_file_path) self._validate_config() def _browse_project_path(self): """浏览项目路径""" path = QFileDialog.getExistingDirectory( self, "选择 ETL 项目目录", self.project_path_edit.text() or str(Path.home()) ) if path: self.project_path_edit.setText(path) # 自动填充 .env 路径 env_path = Path(path) / ".env" if env_path.exists(): self.env_path_edit.setText(str(env_path)) self._validate_config() def _browse_env_path(self): """浏览 .env 文件""" path, _ = QFileDialog.getOpenFileName( self, "选择 .env 文件", self.env_path_edit.text() or str(Path.home()), "环境变量文件 (*.env);;所有文件 (*.*)" ) if path: self.env_path_edit.setText(path) self._validate_config() def _validate_config(self): """验证配置""" project_path = self.project_path_edit.text().strip() env_path = self.env_path_edit.text().strip() issues = [] if not project_path: issues.append("• 未设置 ETL 项目路径") else: p = Path(project_path) if not p.exists(): issues.append(f"• ETL 项目路径不存在") elif not (p / "cli" / "main.py").exists(): issues.append(f"• 找不到 cli/main.py") if not env_path: issues.append("• 未设置 .env 文件路径") elif not Path(env_path).exists(): issues.append("• .env 文件不存在") if issues: self.validation_label.setText("❌ 配置问题:\n" + "\n".join(issues)) self.validation_label.setStyleSheet("color: #d93025;") else: self.validation_label.setText("✅ 配置有效") self.validation_label.setStyleSheet("color: #1e8e3e;") def _save_and_accept(self): """保存并关闭""" project_path = self.project_path_edit.text().strip() env_path = self.env_path_edit.text().strip() # 简单验证 if project_path: p = Path(project_path) if not p.exists(): QMessageBox.warning(self, "警告", "ETL 项目路径不存在") return if not (p / "cli" / "main.py").exists(): reply = QMessageBox.question( self, "确认", "找不到 cli/main.py,确定要使用此路径吗?", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.No: return # 保存设置 app_settings.etl_project_path = project_path if env_path: app_settings.env_file_path = env_path self.accept()