RDSS/temp/quick_config.py

329 lines
12 KiB
Python

#!/usr/bin/env python3
"""
快速配置选项卡
"""
import customtkinter as ctk
from tkinter import filedialog
class QuickConfigTab(ctk.CTkFrame):
def __init__(self, parent):
super().__init__(parent)
# 配置网格布局
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=0)
self.grid_rowconfigure(1, weight=1)
# 基本设置框架
self.basic_frame = ctk.CTkFrame(self)
self.basic_frame.grid(row=0, column=0, sticky="nsew", pady=(0, 10))
self.basic_frame.grid_columnconfigure(0, weight=1)
# 标题
ctk.CTkLabel(
self.basic_frame,
text="基本设置",
font=ctk.CTkFont(size=14, weight="bold")
).grid(row=0, column=0, sticky="w", padx=10, pady=10)
# 事件数量
self.num_events_var = ctk.IntVar(value=8)
self.num_events_var.trace_add('write', self._on_config_change)
ctk.CTkLabel(self.basic_frame, text="事件数量:").grid(row=1, column=0, sticky="w", padx=20, pady=5)
self.num_events_entry = ctk.CTkEntry(
self.basic_frame,
textvariable=self.num_events_var,
width=100
)
self.num_events_entry.grid(row=1, column=0, sticky="w", padx=100, pady=5)
# 事件生成模式
ctk.CTkLabel(self.basic_frame, text="事件生成模式:").grid(row=2, column=0, sticky="w", padx=20, pady=5)
self.generation_mode_var = ctk.StringVar(value="random")
self.generation_mode_var.trace_add('write', self._on_config_change)
mode_frame = ctk.CTkFrame(self.basic_frame)
mode_frame.grid(row=2, column=0, sticky="w", padx=100, pady=5)
ctk.CTkRadioButton(
mode_frame,
text="随机模式",
variable=self.generation_mode_var,
value="random"
).pack(side="left", padx=10)
ctk.CTkRadioButton(
mode_frame,
text="固定模式",
variable=self.generation_mode_var,
value="fixed"
).pack(side="left", padx=10)
ctk.CTkRadioButton(
mode_frame,
text="脉冲模式",
variable=self.generation_mode_var,
value="pulse"
).pack(side="left", padx=10)
# 打包模式
ctk.CTkLabel(self.basic_frame, text="打包模式:").grid(row=3, column=0, sticky="w", padx=20, pady=5)
self.packing_mode_var = ctk.StringVar(value="separate")
self.packing_mode_var.trace_add('write', self._on_config_change)
pack_frame = ctk.CTkFrame(self.basic_frame)
pack_frame.grid(row=3, column=0, sticky="w", padx=100, pady=5)
ctk.CTkRadioButton(
pack_frame,
text="单独打包(每事件一包)",
variable=self.packing_mode_var,
value="separate"
).pack(side="left", padx=10)
ctk.CTkRadioButton(
pack_frame,
text="整体打包(拼接分包)",
variable=self.packing_mode_var,
value="combined"
).pack(side="left", padx=10)
# 输出格式
ctk.CTkLabel(self.basic_frame, text="输出格式:").grid(row=4, column=0, sticky="w", padx=20, pady=5)
self.output_format_var = ctk.StringVar(value="all")
format_frame = ctk.CTkFrame(self.basic_frame)
format_frame.grid(row=4, column=0, sticky="w", padx=100, pady=5)
self.bin_var = ctk.BooleanVar(value=True)
self.txt_var = ctk.BooleanVar(value=True)
self.debug_var = ctk.BooleanVar(value=False)
ctk.CTkCheckBox(
format_frame,
text="二进制(.bin)",
variable=self.bin_var
).pack(side="left", padx=10)
ctk.CTkCheckBox(
format_frame,
text="文本",
variable=self.txt_var
).pack(side="left", padx=10)
ctk.CTkCheckBox(
format_frame,
text="调试文本",
variable=self.debug_var
).pack(side="left", padx=10)
# 输出文件名
ctk.CTkLabel(self.basic_frame, text="输出文件名:").grid(row=5, column=0, sticky="w", padx=20, pady=5)
self.output_file_var = ctk.StringVar(value="detector_random_separate_8events")
self._user_modified = False # 标记用户是否手动修改过文件名
file_frame = ctk.CTkFrame(self.basic_frame)
file_frame.grid(row=5, column=0, sticky="w", padx=100, pady=5)
self.output_entry = ctk.CTkEntry(
file_frame,
textvariable=self.output_file_var,
width=200
)
self.output_entry.pack(side="left", padx=5)
self.output_file_var.trace_add('write', self._on_output_file_changed)
ctk.CTkButton(
file_frame,
text="浏览...",
width=80,
command=self.browse_output_file
).pack(side="left", padx=5)
# 随机模式参数
self.random_params_frame = ctk.CTkFrame(self.basic_frame)
self.random_params_frame.grid(row=6, column=0, sticky="nsew", padx=20, pady=10)
# 标题
ctk.CTkLabel(
self.random_params_frame,
text="随机模式参数",
font=ctk.CTkFont(size=12, weight="bold")
).grid(row=0, column=0, sticky="w", padx=20, pady=10)
# 每探测器最少信号
ctk.CTkLabel(self.random_params_frame, text="每探测器最少信号:").grid(row=1, column=0, sticky="w", padx=40, pady=5)
self.min_signals_var = ctk.IntVar(value=1)
ctk.CTkEntry(
self.random_params_frame,
textvariable=self.min_signals_var,
width=100
).grid(row=1, column=1, sticky="w", padx=10, pady=5)
# 每探测器最多信号
ctk.CTkLabel(self.random_params_frame, text="每探测器最多信号:").grid(row=2, column=0, sticky="w", padx=40, pady=5)
self.max_signals_var = ctk.IntVar(value=10)
ctk.CTkEntry(
self.random_params_frame,
textvariable=self.max_signals_var,
width=100
).grid(row=2, column=1, sticky="w", padx=10, pady=5)
# 要求有信号才输出
self.require_signal_var = ctk.BooleanVar(value=True)
ctk.CTkCheckBox(
self.random_params_frame,
text="要求有信号才输出",
variable=self.require_signal_var
).grid(row=3, column=0, columnspan=2, sticky="w", padx=40, pady=10)
# 绑定事件生成模式变化,控制随机模式参数的显示
self.generation_mode_var.trace_add('write', self._on_generation_mode_change)
# 初始显示控制
self._on_generation_mode_change()
def _on_config_change(self, *args):
"""配置变化时自动更新输出文件名(仅当用户未手动修改时)"""
if not self._user_modified:
generation_mode = self.generation_mode_var.get()
packing_mode = self.packing_mode_var.get()
num_events = self.num_events_var.get()
# 生成文件名: detector_{生成模式}_{打包模式}_{数量}events
output_filename = f"detector_{generation_mode}_{packing_mode}_{num_events}events"
self.output_file_var.set(output_filename)
def _on_output_file_focus_in(self, event):
"""当输出文件名文本框获得焦点时,标记用户可能会手动修改"""
pass
def _on_output_file_changed(self, *args):
"""当输出文件名被手动修改时"""
self._user_modified = True
def _on_generation_mode_change(self, *args):
"""事件生成模式变化时控制随机模式参数的显示"""
mode = self.generation_mode_var.get()
if mode == "random":
self.random_params_frame.grid()
else:
self.random_params_frame.grid_remove()
def browse_output_file(self):
"""浏览输出文件路径"""
filename = filedialog.asksaveasfilename(
defaultextension=".bin",
filetypes=[("Binary files", "*.bin"), ("All files", "*.*")]
)
if filename:
import os
self.output_file_var.set(os.path.splitext(filename)[0])
def set_test_preset(self):
"""测试模式预设"""
self.num_events_var.set(3)
self.generation_mode_var.set("fixed")
self.packing_mode_var.set("separate")
self.bin_var.set(True)
self.txt_var.set(True)
self.debug_var.set(True)
self.output_file_var.set("test_output")
def set_high_precision_preset(self):
"""高精度模拟预设"""
self.num_events_var.set(20)
self.generation_mode_var.set("random")
self.packing_mode_var.set("combined")
self.bin_var.set(True)
self.txt_var.set(True)
self.debug_var.set(False)
self.output_file_var.set("high_precision_output")
def set_quick_preset(self):
"""快速生成预设"""
self.num_events_var.set(1)
self.generation_mode_var.set("pulse")
self.packing_mode_var.set("separate")
self.bin_var.set(True)
self.txt_var.set(False)
self.debug_var.set(False)
self.output_file_var.set("quick_output")
def set_custom_preset(self):
"""自定义预设"""
# 保持当前设置不变
pass
def get_config(self):
"""获取配置"""
config = {
"num_events": self.num_events_var.get(),
"event_generation_mode": self.generation_mode_var.get(),
"packing_mode": self.packing_mode_var.get(),
"output_format": self._get_output_format(),
"output_file": self.output_file_var.get()
}
# 添加随机模式参数
if self.generation_mode_var.get() == "random":
config["sampling"] = {
"min_signals_per_detector": self.min_signals_var.get(),
"max_signals_per_detector": self.max_signals_var.get(),
"require_signal": self.require_signal_var.get()
}
return config
def set_config(self, config):
"""设置配置"""
if "num_events" in config:
self.num_events_var.set(config["num_events"])
if "event_generation_mode" in config:
self.generation_mode_var.set(config["event_generation_mode"])
if "packing_mode" in config:
self.packing_mode_var.set(config["packing_mode"])
if "output_format" in config:
self._set_output_format(config["output_format"])
if "output_file" in config:
self.output_file_var.set(config["output_file"])
# 设置随机模式参数
if "sampling" in config:
sampling = config["sampling"]
if "min_signals_per_detector" in sampling:
self.min_signals_var.set(sampling["min_signals_per_detector"])
if "max_signals_per_detector" in sampling:
self.max_signals_var.set(sampling["max_signals_per_detector"])
if "require_signal" in sampling:
self.require_signal_var.set(sampling["require_signal"])
# 控制随机模式参数的显示
self._on_generation_mode_change()
def _get_output_format(self):
"""获取输出格式"""
formats = []
if self.bin_var.get():
formats.append("binary")
if self.txt_var.get():
formats.append("text")
if self.debug_var.get():
formats.append("debug")
if not formats:
return "binary"
if len(formats) == 3:
return "all"
return formats[0]
def _set_output_format(self, format_str):
"""设置输出格式"""
if format_str == "all":
self.bin_var.set(True)
self.txt_var.set(True)
self.debug_var.set(True)
elif format_str == "binary":
self.bin_var.set(True)
self.txt_var.set(False)
self.debug_var.set(False)
elif format_str == "text":
self.bin_var.set(False)
self.txt_var.set(True)
self.debug_var.set(False)
elif format_str == "debug":
self.bin_var.set(False)
self.txt_var.set(False)
self.debug_var.set(True)