You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			223 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
		
		
			
		
	
	
			223 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
|   
											1 month ago
										 | import tkinter as tk | ||
|  | from tkinter import ttk | ||
|  | from .base_page import BasePage | ||
|  | from protocol import DbgConfigPort | ||
|  | from config import Cmd | ||
|  | 
 | ||
|  | 
 | ||
|  | class PortParamsPage(BasePage): | ||
|  |     def __init__(self, parent, tcp_client): | ||
|  | 
 | ||
|  |         self.current_channel = 1 | ||
|  | 
 | ||
|  |         super().__init__(parent, tcp_client, "通道参数") | ||
|  | 
 | ||
|  |         self.configure_styles() | ||
|  | 
 | ||
|  |         # 注册回调 | ||
|  |         tcp_client.register_callback(Cmd.PORT_PARAM_GET, self.on_data_received) | ||
|  |         tcp_client.register_callback(Cmd.PORT_PARAM_SET, self.on_set_response) | ||
|  | 
 | ||
|  |         self.current_channel = 1  # 默认通道1 | ||
|  |         # self.create_widgets() | ||
|  | 
 | ||
|  |     def configure_styles(self): | ||
|  |         """配置界面样式""" | ||
|  |         style = ttk.Style() | ||
|  |         style.configure('Readonly.TEntry', | ||
|  |                         fieldbackground='#f0f0f0', | ||
|  |                         foreground='#666666') | ||
|  | 
 | ||
|  |     def create_widgets(self): | ||
|  |         """创建界面控件""" | ||
|  |         super().create_widgets() | ||
|  | 
 | ||
|  |         # 创建主框架 | ||
|  |         main_frame = ttk.Frame(self) | ||
|  |         main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) | ||
|  | 
 | ||
|  |         # 通道选择区域 | ||
|  |         channel_frame = ttk.LabelFrame(main_frame, text="通道选择") | ||
|  |         channel_frame.pack(fill=tk.X, pady=5) | ||
|  | 
 | ||
|  |         ttk.Label(channel_frame, text="通道号:").pack(side=tk.LEFT, padx=5) | ||
|  |         self.channel_var = tk.IntVar(value=self.current_channel) | ||
|  |         channel_spin = ttk.Spinbox(channel_frame, from_=1, to=8, | ||
|  |                                    textvariable=self.channel_var, width=5, | ||
|  |                                    command=self.on_channel_changed) | ||
|  |         channel_spin.pack(side=tk.LEFT, padx=5) | ||
|  | 
 | ||
|  |         # 创建两列参数区域 | ||
|  |         param_frame = ttk.Frame(main_frame) | ||
|  |         param_frame.pack(fill=tk.BOTH, expand=True, pady=5) | ||
|  | 
 | ||
|  |         left_frame = ttk.Frame(param_frame) | ||
|  |         left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5)) | ||
|  | 
 | ||
|  |         right_frame = ttk.Frame(param_frame) | ||
|  |         right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0)) | ||
|  | 
 | ||
|  |         # 定义所有字段 | ||
|  |         self.fields = [ | ||
|  |             # 左列 - 基本参数 | ||
|  |             {"label": "通道类型", "attr": "channel_type", "type": "spin", "args": (0, 255), "readonly": False}, | ||
|  |             {"label": "过滤频率", "attr": "filter_frequency", "type": "entry", "readonly": False}, | ||
|  |             {"label": "上升时间", "attr": "rise_time", "type": "spin", "args": (-32768, 32767), "unit": "ns", | ||
|  |              "readonly": False}, | ||
|  |             {"label": "峰值时间", "attr": "peak_time", "type": "spin", "args": (-32768, 32767), "unit": "ns", | ||
|  |              "readonly": False}, | ||
|  |             {"label": "下降时间", "attr": "fall_time", "type": "spin", "args": (-32768, 32767), "unit": "ns", | ||
|  |              "readonly": False}, | ||
|  |             {"label": "脉冲宽度", "attr": "pulse_width", "type": "spin", "args": (-32768, 32767), "unit": "ns", | ||
|  |              "readonly": False}, | ||
|  |             {"label": "波峰数量", "attr": "peak_count", "type": "spin", "args": (-32768, 32767), "readonly": False}, | ||
|  | 
 | ||
|  |             # 右列 - 信号参数 | ||
|  |             {"label": "信号包络面", "attr": "signal_envelope", "type": "entry", "readonly": False}, | ||
|  |             {"label": "信号平均值", "attr": "signal_mean", "type": "float_entry", "readonly": False}, | ||
|  |             {"label": "信号方差值", "attr": "signal_variance", "type": "float_entry", "readonly": False}, | ||
|  |             {"label": "第一主频", "attr": "primary_frequency", "type": "entry", "readonly": False}, | ||
|  |             {"label": "第一主频峰值", "attr": "primary_freq_peak", "type": "spin", "args": (-32768, 32767), | ||
|  |              "readonly": False}, | ||
|  |             {"label": "谱峰个数", "attr": "spectral_peak_count", "type": "spin", "args": (-32768, 32767), | ||
|  |              "readonly": False}, | ||
|  |             {"label": "频谱均值", "attr": "spectrum_mean", "type": "float_entry", "readonly": False}, | ||
|  |             {"label": "频谱方差值", "attr": "spectrum_variance", "type": "float_entry", "readonly": False}, | ||
|  |         ] | ||
|  | 
 | ||
|  |         # 创建字段控件 | ||
|  |         self.create_field_controls(left_frame, self.fields[:7]) | ||
|  |         self.create_field_controls(right_frame, self.fields[7:]) | ||
|  | 
 | ||
|  |         # 创建按钮 | ||
|  |         self.create_buttons() | ||
|  | 
 | ||
|  |     def create_field_controls(self, parent, fields): | ||
|  |         """创建字段控件""" | ||
|  |         for i, field in enumerate(fields): | ||
|  |             label_text = field["label"] + ":" | ||
|  |             if "unit" in field and field["unit"]: | ||
|  |                 label_text += f" ({field['unit']})" | ||
|  | 
 | ||
|  |             ttk.Label(parent, text=label_text).grid( | ||
|  |                 row=i, column=0, sticky='e', padx=2, pady=2) | ||
|  | 
 | ||
|  |             if field["type"] == "spin": | ||
|  |                 var = tk.IntVar() | ||
|  |                 spinbox = ttk.Spinbox(parent, from_=field["args"][0], to=field["args"][1], | ||
|  |                                       textvariable=var, width=12) | ||
|  |                 spinbox.grid(row=i, column=1, sticky='w', padx=2, pady=2) | ||
|  | 
 | ||
|  |             elif field["type"] == "float_entry": | ||
|  |                 var = tk.DoubleVar() | ||
|  |                 entry = ttk.Entry(parent, textvariable=var, width=12) | ||
|  |                 entry.grid(row=i, column=1, sticky='w', padx=2, pady=2) | ||
|  | 
 | ||
|  |             else:  # entry | ||
|  |                 var = tk.StringVar() | ||
|  |                 entry = ttk.Entry(parent, textvariable=var, width=12) | ||
|  |                 entry.grid(row=i, column=1, sticky='w', padx=2, pady=2) | ||
|  | 
 | ||
|  |             setattr(self, f"{field['attr']}_var", var) | ||
|  | 
 | ||
|  |     def create_buttons(self): | ||
|  |         """创建按钮""" | ||
|  |         btn_frame = ttk.Frame(self) | ||
|  |         btn_frame.pack(pady=10) | ||
|  | 
 | ||
|  |         ttk.Button(btn_frame, text="读取", command=self.read_data, width=10).pack(side=tk.LEFT, padx=5) | ||
|  |         ttk.Button(btn_frame, text="设置", command=self.set_data, width=10).pack(side=tk.LEFT, padx=5) | ||
|  |         ttk.Button(btn_frame, text="重置", command=self.reset_fields, width=10).pack(side=tk.LEFT, padx=5) | ||
|  | 
 | ||
|  |     def on_channel_changed(self): | ||
|  |         """通道号改变事件""" | ||
|  |         self.current_channel = self.channel_var.get() | ||
|  |         print(f"切换到通道 {self.current_channel}") | ||
|  | 
 | ||
|  |     def read_data(self): | ||
|  |         """读取通道参数""" | ||
|  |         if not self.tcp_client.connected: | ||
|  |             self.show_error("未连接设备") | ||
|  |             return | ||
|  | 
 | ||
|  |         # 发送读取命令,包含通道号 | ||
|  |         channel_data = self.current_channel.to_bytes(1, 'little') | ||
|  |         self.tcp_client.send_packet(Cmd.PORT_PARAM_GET, channel_data) | ||
|  | 
 | ||
|  |     def set_data(self): | ||
|  |         """设置通道参数""" | ||
|  |         if not self.tcp_client.connected: | ||
|  |             self.show_error("未连接设备") | ||
|  |             return | ||
|  | 
 | ||
|  |         try: | ||
|  |             config = DbgConfigPort() | ||
|  |             config.vport = self.current_channel | ||
|  | 
 | ||
|  |             # 设置字段值 | ||
|  |             config.channel_type = self.channel_type_var.get() | ||
|  |             config.filter_frequency = int(self.filter_frequency_var.get() or 0) | ||
|  |             config.rise_time = self.rise_time_var.get() | ||
|  |             config.peak_time = self.peak_time_var.get() | ||
|  |             config.fall_time = self.fall_time_var.get() | ||
|  |             config.pulse_width = self.pulse_width_var.get() | ||
|  |             config.peak_count = self.peak_count_var.get() | ||
|  |             config.signal_envelope = int(self.signal_envelope_var.get() or 0) | ||
|  |             config.signal_mean = float(self.signal_mean_var.get() or 0) | ||
|  |             config.signal_variance = float(self.signal_variance_var.get() or 0) | ||
|  |             config.primary_frequency = int(self.primary_frequency_var.get() or 0) | ||
|  |             config.primary_freq_peak = self.primary_freq_peak_var.get() | ||
|  |             config.spectral_peak_count = self.spectral_peak_count_var.get() | ||
|  |             config.spectrum_mean = float(self.spectrum_mean_var.get() or 0) | ||
|  |             config.spectrum_variance = float(self.spectrum_variance_var.get() or 0) | ||
|  | 
 | ||
|  |             # 发送设置命令 | ||
|  |             self.tcp_client.send_packet(Cmd.PORT_PARAM_SET, config.to_bytes()) | ||
|  | 
 | ||
|  |         except ValueError as e: | ||
|  |             self.show_error(f"参数格式错误: {e}") | ||
|  |         except Exception as e: | ||
|  |             self.show_error(f"设置失败: {e}") | ||
|  | 
 | ||
|  |     def reset_fields(self): | ||
|  |         """重置所有字段为默认值""" | ||
|  |         for field in self.fields: | ||
|  |             var = getattr(self, f"{field['attr']}_var") | ||
|  |             if field["type"] == "spin": | ||
|  |                 var.set(0) | ||
|  |             elif field["type"] == "float_entry": | ||
|  |                 var.set(0.0) | ||
|  |             else: | ||
|  |                 var.set("") | ||
|  | 
 | ||
|  |     def on_data_received(self, header, body): | ||
|  |         """处理接收到的通道参数""" | ||
|  |         try: | ||
|  |             config = DbgConfigPort.from_bytes(body) | ||
|  | 
 | ||
|  |             # 更新界面字段 | ||
|  |             self.channel_type_var.set(config.channel_type) | ||
|  |             self.filter_frequency_var.set(str(config.filter_frequency)) | ||
|  |             self.rise_time_var.set(config.rise_time) | ||
|  |             self.peak_time_var.set(config.peak_time) | ||
|  |             self.fall_time_var.set(config.fall_time) | ||
|  |             self.pulse_width_var.set(config.pulse_width) | ||
|  |             self.peak_count_var.set(config.peak_count) | ||
|  |             self.signal_envelope_var.set(str(config.signal_envelope)) | ||
|  |             self.signal_mean_var.set(config.signal_mean) | ||
|  |             self.signal_variance_var.set(config.signal_variance) | ||
|  |             self.primary_frequency_var.set(str(config.primary_frequency)) | ||
|  |             self.primary_freq_peak_var.set(config.primary_freq_peak) | ||
|  |             self.spectral_peak_count_var.set(config.spectral_peak_count) | ||
|  |             self.spectrum_mean_var.set(config.spectrum_mean) | ||
|  |             self.spectrum_variance_var.set(config.spectrum_variance) | ||
|  | 
 | ||
|  |             print(f"通道 {self.current_channel} 参数读取成功") | ||
|  | 
 | ||
|  |         except Exception as e: | ||
|  |             print(f"解析通道参数失败: {e}") | ||
|  |             self.show_error("解析通道参数失败") | ||
|  | 
 | ||
|  |     def on_set_response(self, header, body): | ||
|  |         """处理设置响应""" | ||
|  |         self.show_info(f"通道 {self.current_channel} 参数设置成功") |