#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2025 Any2MIF Project # All rights reserved. """ Any2MIF - 参数配置面板 负责MIF转换的参数设置 """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSpinBox, QLineEdit, QGroupBox, QFormLayout, QCheckBox, QSlider ) from PyQt6.QtCore import Qt, QSettings, QRegularExpression from PyQt6.QtGui import QRegularExpressionValidator class ParamPanel(QWidget): """参数配置面板""" def __init__(self, settings: QSettings, parent=None): """初始化参数配置面板""" super().__init__(parent) self.settings = settings self._init_ui() self._load_settings() self._connect_signals() def _init_ui(self): """初始化UI""" # 创建主布局 layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) # 创建标题标签 title_label = QLabel("参数配置") title_label.setStyleSheet("font-weight: bold; font-size: 14px;") layout.addWidget(title_label) # 创建基本参数组 basic_group = QGroupBox("基本参数") basic_layout = QFormLayout(basic_group) layout.addWidget(basic_group) # WIDTH 参数 self.width_combo = QComboBox() self.width_combo.addItems(["8位", "16位", "32位"]) basic_layout.addRow("数据宽度 (WIDTH):", self.width_combo) # DEPTH 参数 self.depth_layout = QHBoxLayout() self.auto_depth_check = QCheckBox("自动计算") self.auto_depth_check.setChecked(True) self.depth_spin = QSpinBox() self.depth_spin.setRange(1, 1000000) self.depth_spin.setValue(1024) self.depth_spin.setEnabled(False) self.depth_layout.addWidget(self.auto_depth_check) self.depth_layout.addWidget(self.depth_spin) basic_layout.addRow("深度 (DEPTH):", self.depth_layout) # 基数设置 self.radix_combo = QComboBox() self.radix_combo.addItems(["十六进制 (HEX)", "二进制 (BIN)", "十进制 (DEC)"]) basic_layout.addRow("数据格式:", self.radix_combo) # 地址偏移量 self.offset_edit = QLineEdit("0") # 设置十六进制验证器 hex_validator = QRegularExpressionValidator(QRegularExpression("0x[0-9A-Fa-f]+|[0-9A-Fa-f]+")) self.offset_edit.setValidator(hex_validator) self.offset_edit.setPlaceholderText("十六进制值 (例如: 0x100)") basic_layout.addRow("地址偏移量:", self.offset_edit) # 创建高级参数组 advanced_group = QGroupBox("高级参数") advanced_layout = QFormLayout(advanced_group) layout.addWidget(advanced_group) # 文件头始终添加,不再提供选项 # 地址格式 self.addr_format_combo = QComboBox() self.addr_format_combo.addItems(["标准格式 (@XXXX)", "紧凑格式 (XXXX:)"]) advanced_layout.addRow("地址格式:", self.addr_format_combo) # 地址进制 self.addr_radix_combo = QComboBox() self.addr_radix_combo.addItems(["十六进制 (HEX)", "二进制 (BIN)", "十进制 (DEC)"]) advanced_layout.addRow("地址进制:", self.addr_radix_combo) # 每行数据数量 self.data_per_line_spin = QSpinBox() self.data_per_line_spin.setRange(1, 16) self.data_per_line_spin.setValue(1) advanced_layout.addRow("每行数据数量:", self.data_per_line_spin) # 添加弹性空间 layout.addStretch(1) def _load_settings(self): """加载设置""" # 加载WIDTH设置 width_index = self.settings.value("params/width_index", 0, int) self.width_combo.setCurrentIndex(width_index) # 加载DEPTH设置 auto_depth = self.settings.value("params/auto_depth", True, bool) self.auto_depth_check.setChecked(auto_depth) self.depth_spin.setEnabled(not auto_depth) depth = self.settings.value("params/depth", 1024, int) self.depth_spin.setValue(depth) # 加载基数设置 radix_index = self.settings.value("params/radix_index", 0, int) self.radix_combo.setCurrentIndex(radix_index) # 加载地址偏移量 offset = self.settings.value("params/offset", "0") self.offset_edit.setText(offset) # 加载高级设置 addr_format_index = self.settings.value("params/addr_format_index", 0, int) self.addr_format_combo.setCurrentIndex(addr_format_index) addr_radix_index = self.settings.value("params/addr_radix_index", 0, int) self.addr_radix_combo.setCurrentIndex(addr_radix_index) data_per_line = self.settings.value("params/data_per_line", 1, int) self.data_per_line_spin.setValue(data_per_line) def _connect_signals(self): """连接信号和槽""" # 自动深度复选框 self.auto_depth_check.toggled.connect(self._on_auto_depth_toggled) # 保存设置 self.width_combo.currentIndexChanged.connect(self._save_settings) self.auto_depth_check.toggled.connect(self._save_settings) self.depth_spin.valueChanged.connect(self._save_settings) self.radix_combo.currentIndexChanged.connect(self._save_settings) self.offset_edit.editingFinished.connect(self._save_settings) # 文件头选项已移除 self.addr_format_combo.currentIndexChanged.connect(self._save_settings) self.addr_radix_combo.currentIndexChanged.connect(self._save_settings) self.data_per_line_spin.valueChanged.connect(self._save_settings) def _on_auto_depth_toggled(self, checked): """处理自动深度复选框切换事件""" self.depth_spin.setEnabled(not checked) def _save_settings(self): """保存设置""" self.settings.setValue("params/width_index", self.width_combo.currentIndex()) self.settings.setValue("params/auto_depth", self.auto_depth_check.isChecked()) self.settings.setValue("params/depth", self.depth_spin.value()) self.settings.setValue("params/radix_index", self.radix_combo.currentIndex()) self.settings.setValue("params/offset", self.offset_edit.text()) # 文件头设置已移除,始终为True self.settings.setValue("params/header", True) self.settings.setValue("params/addr_format_index", self.addr_format_combo.currentIndex()) self.settings.setValue("params/addr_radix_index", self.addr_radix_combo.currentIndex()) self.settings.setValue("params/data_per_line", self.data_per_line_spin.value()) def get_params(self): """获取参数""" # 获取WIDTH值 width_map = {0: 8, 1: 16, 2: 32} width = width_map[self.width_combo.currentIndex()] # 获取DEPTH值 auto_depth = self.auto_depth_check.isChecked() depth = self.depth_spin.value() if not auto_depth else None # 获取基数 radix_map = {0: "HEX", 1: "BIN", 2: "DEC"} radix = radix_map[self.radix_combo.currentIndex()] # 获取地址偏移量 offset_text = self.offset_edit.text() if offset_text.startswith("0x"): offset = int(offset_text, 16) else: offset = int(offset_text, 16) # 获取高级参数 addr_format = "standard" if self.addr_format_combo.currentIndex() == 0 else "compact" # 获取地址进制 addr_radix_map = {0: "HEX", 1: "BIN", 2: "DEC"} addr_radix = addr_radix_map[self.addr_radix_combo.currentIndex()] data_per_line = self.data_per_line_spin.value() # 返回参数字典 return { "width": width, "auto_depth": auto_depth, "depth": depth, "radix": radix, "offset": offset, "header": True, # 始终添加文件头 "addr_format": addr_format, "addr_radix": addr_radix, "data_per_line": data_per_line }