#!/usr/bin/env python # -*- coding: utf-8 -*- """ Step8_75 面板 - 自定义回归预测 """ import os from PyQt5.QtWidgets import ( QWidget, QVBoxLayout, QGroupBox, QPushButton, QCheckBox, QMessageBox, QFileDialog, ) from src.gui.components.custom_widgets import FileSelectWidget from src.gui.styles import ModernStylesheet class Step8_75Panel(QWidget): """步骤8.75:自定义回归预测""" def __init__(self, parent=None): super().__init__(parent) self.init_ui() def init_ui(self): layout = QVBoxLayout() # 采样光谱CSV文件选择 self.sampling_csv_file = FileSelectWidget( "采样光谱CSV:", "CSV Files (*.csv);;All Files (*.*)" ) layout.addWidget(self.sampling_csv_file) # 自定义回归模型目录选择(9_Custom_Regression_Modeling) self.regression_models_dir = FileSelectWidget( "回归模型目录:", "Directories;;All Files (*.*)" ) self.regression_models_dir.label.setText("回归模型目录:") self.regression_models_dir.browse_btn.clicked.disconnect() self.regression_models_dir.browse_btn.clicked.connect(self.browse_regression_models_dir) self.regression_models_dir.set_path("") # 路径由 update_from_config 根据 work_dir 自动填充 layout.addWidget(self.regression_models_dir) # 公式CSV文件选择(用于查找index_formula) self.formula_csv_file = FileSelectWidget( "公式CSV文件:", "CSV Files (*.csv);;All Files (*.*)" ) self.formula_csv_file.label.setText("公式CSV文件:") layout.addWidget(self.formula_csv_file) # 输出目录选择 self.output_dir_widget = FileSelectWidget( "输出目录:", "Directories;;All Files (*.*)" ) self.output_dir_widget.label.setText("输出目录:") self.output_dir_widget.browse_btn.clicked.disconnect() self.output_dir_widget.browse_btn.clicked.connect(self.browse_output_dir) self.output_dir_widget.line_edit.setPlaceholderText("留空使用默认prediction目录") layout.addWidget(self.output_dir_widget) # 启用步骤 self.enable_checkbox = QCheckBox("启用此步骤") self.enable_checkbox.setChecked(True) layout.addWidget(self.enable_checkbox) # 独立运行按钮 self.run_button = QPushButton("独立运行此步骤") self.run_button.setStyleSheet(ModernStylesheet.get_button_stylesheet('success')) self.run_button.clicked.connect(self.run_step) layout.addWidget(self.run_button) layout.addStretch() self.setLayout(layout) def update_from_config(self, work_dir=None, pipeline=None): """从全局配置自动填充采样光谱和自定义回归模型目录 Args: work_dir: 工作目录路径 pipeline: Pipeline 实例(未使用,保留接口兼容性) """ if work_dir: self.work_dir = work_dir elif hasattr(self, 'work_dir') and self.work_dir: pass else: self.work_dir = None main_window = self.window() # 1. 尝试从 Step7 界面读取全湖采样点 CSV 路径 if main_window and hasattr(main_window, 'step7_panel'): step7_output_path = main_window.step7_panel.output_file.get_path() if step7_output_path: # 若为相对路径,使用 work_dir 合成为绝对路径 if not os.path.isabs(step7_output_path): step7_output_path = os.path.join(self.work_dir or '', step7_output_path).replace('\\', '/') existing = self.sampling_csv_file.get_path() if not existing or not existing.strip(): self.sampling_csv_file.set_path(step7_output_path) # 2. 尝试从 Step6.75 界面读取自定义回归模型目录 if main_window and hasattr(main_window, 'step6_75_panel'): step6_75_models_dir = main_window.step6_75_panel.output_dir.text().strip() if step6_75_models_dir: # 若为相对路径,使用 work_dir 合成为绝对路径 if not os.path.isabs(step6_75_models_dir): step6_75_models_dir = os.path.join(self.work_dir or '', step6_75_models_dir).replace('\\', '/') existing_models = self.regression_models_dir.get_path() if not existing_models or not existing_models.strip(): self.regression_models_dir.set_path(step6_75_models_dir) # 3. 自动填充回归模型目录(如果 step6_75 未提供) if self.work_dir: models_dir = self.regression_models_dir.get_path().strip() if not models_dir: default_models_dir = os.path.join(self.work_dir, "9_Custom_Regression_Modeling").replace('\\', '/') self.regression_models_dir.set_path(default_models_dir) # 4. 自动填充输出目录(自定义回归预测目录) if self.work_dir: output_dir = os.path.join(self.work_dir, "11_12_13_predictions/Custom_Regression_Prediction") os.makedirs(output_dir, exist_ok=True) existing_out = self.output_dir_widget.get_path() if not existing_out or not existing_out.strip(): self.output_dir_widget.set_path(output_dir) def _get_default_work_dir(self): """获取 work_dir,优先用 panel 自身缓存的,否则尝试从主窗口取""" if hasattr(self, 'work_dir') and self.work_dir: return str(self.work_dir) mw = self.window() if mw and hasattr(mw, 'work_dir') and mw.work_dir: return str(mw.work_dir) return "" def browse_regression_models_dir(self): """浏览回归模型目录""" default = self._get_default_work_dir() if default: default = os.path.join(default, "9_Custom_Regression_Modeling") dir_path = QFileDialog.getExistingDirectory(self, "选择回归模型目录", default) if dir_path: self.regression_models_dir.set_path(dir_path) def browse_output_dir(self): """浏览输出目录""" default = self._get_default_work_dir() if default: default = os.path.join(default, "11_12_13_predictions/Custom_Regression_Prediction") dir_path = QFileDialog.getExistingDirectory(self, "选择输出目录", default) if dir_path: self.output_dir_widget.set_path(dir_path) def get_config(self): """获取配置""" config = { 'enabled': self.enable_checkbox.isChecked() } sampling_csv_path = self.sampling_csv_file.get_path() if sampling_csv_path: config['sampling_csv_path'] = sampling_csv_path regression_models_dir = self.regression_models_dir.get_path() if regression_models_dir: config['custom_regression_dir'] = regression_models_dir formula_csv_path = self.formula_csv_file.get_path() if formula_csv_path: config['formula_csv_path'] = formula_csv_path output_dir = self.output_dir_widget.get_path() if output_dir: config['output_dir'] = output_dir return config def set_config(self, config): """设置配置""" if 'sampling_csv_path' in config: self.sampling_csv_file.set_path(config['sampling_csv_path']) if 'custom_regression_dir' in config: self.regression_models_dir.set_path(config['custom_regression_dir']) if 'formula_csv_path' in config: self.formula_csv_file.set_path(config['formula_csv_path']) if 'output_dir' in config: self.output_dir_widget.set_path(config['output_dir']) if 'enabled' in config: self.enable_checkbox.setChecked(config['enabled']) def run_step(self): """独立运行步骤8.75""" sampling_csv_path = self.sampling_csv_file.get_path() if not sampling_csv_path: QMessageBox.warning(self, "输入错误", "请选择采样光谱CSV文件!") return regression_models_dir = self.regression_models_dir.get_path() if not regression_models_dir: QMessageBox.warning(self, "输入错误", "请选择回归模型目录!") return config = self.get_config() parent = self.parent() while parent and not hasattr(parent, 'run_single_step'): parent = parent.parent() if parent and hasattr(parent, 'run_single_step'): parent.run_single_step('step8_75', {'step8_75': config}) else: QMessageBox.critical(self, "错误", "无法找到父级GUI对象")