#!/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)