PCM_Report/config_category_widget.py

161 lines
5.1 KiB
Python

"""
配置分类选择组件
"""
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QComboBox, QPushButton, QMessageBox
)
from PySide6.QtCore import Signal, Qt
from pathlib import Path
from typing import Optional, Callable
from config_category import ConfigCategoryManager, ConfigCategory
class ConfigCategoryWidget(QWidget):
"""配置分类选择组件"""
# 信号:分类改变时触发 (category_name, config_path, template_path)
category_changed = Signal(str, Path, object)
def __init__(self, parent: Optional[QWidget] = None,
on_change: Optional[Callable] = None):
super().__init__(parent)
self._on_change = on_change
self.manager = ConfigCategoryManager()
self._current_category: Optional[ConfigCategory] = None
self._init_ui()
self._load_categories()
def _init_ui(self):
"""初始化UI"""
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
# 标签
label = QLabel("配置分类:")
label.setStyleSheet("font-weight: bold; font-size: 13px;")
layout.addWidget(label)
# 分类下拉框
self.category_combo = QComboBox()
self.category_combo.setMinimumWidth(150)
self.category_combo.currentIndexChanged.connect(self._on_category_selected)
layout.addWidget(self.category_combo)
# 刷新按钮
refresh_btn = QPushButton("刷新")
refresh_btn.setMaximumWidth(60)
refresh_btn.clicked.connect(self._load_categories)
layout.addWidget(refresh_btn)
# 信息标签
self.info_label = QLabel("")
self.info_label.setStyleSheet("color: #666; font-size: 11px;")
layout.addWidget(self.info_label)
layout.addStretch()
self.setLayout(layout)
def _load_categories(self):
"""加载配置分类列表"""
# 保存当前选择
current_name = self.get_current_category_name()
# 清空并重新加载
self.category_combo.clear()
categories = self.manager.scan_categories()
if not categories:
self.category_combo.addItem("(无可用分类)", None)
self.info_label.setText("请在 configs/ 目录下创建分类")
self.info_label.setStyleSheet("color: #f57c00; font-size: 11px;")
return
# 添加分类到下拉框
for category in categories:
self.category_combo.addItem(category.name, category)
# 恢复之前的选择
if current_name:
index = self.category_combo.findText(current_name)
if index >= 0:
self.category_combo.setCurrentIndex(index)
# 更新信息
self._update_info()
def _on_category_selected(self, index: int):
"""分类选择改变"""
if index < 0:
return
category = self.category_combo.itemData(index)
if category is None:
return
self._current_category = category
self._update_info()
# 触发信号
template_path = category.template_path if category.template_path else None
self.category_changed.emit(
category.name,
category.config_path,
template_path
)
# 调用回调
if self._on_change:
self._on_change()
def _update_info(self):
"""更新信息标签"""
if self._current_category is None:
self.info_label.setText("")
return
cat = self._current_category
has_template = cat.template_path is not None
if has_template:
template_name = cat.template_path.name
self.info_label.setText(f"✓ 配置和模板已就绪 ({template_name})")
self.info_label.setStyleSheet("color: #2e7d32; font-size: 11px;")
else:
self.info_label.setText("⚠ 未找到模板文件")
self.info_label.setStyleSheet("color: #f57c00; font-size: 11px;")
def get_current_category(self) -> Optional[ConfigCategory]:
"""获取当前选择的分类"""
return self._current_category
def get_current_category_name(self) -> Optional[str]:
"""获取当前分类名称"""
if self._current_category:
return self._current_category.name
return None
def set_category(self, name: str) -> bool:
"""
设置当前分类
Args:
name: 分类名称
Returns:
是否成功设置
"""
index = self.category_combo.findText(name)
if index >= 0:
self.category_combo.setCurrentIndex(index)
return True
return False
def has_categories(self) -> bool:
"""是否有可用的分类"""
return self.category_combo.count() > 0 and \
self.category_combo.itemData(0) is not None