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
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} 参数设置成功") |