|
|
|
|
@ -37,9 +37,12 @@ class WaveformPage(BasePage):
|
|
|
|
|
|
|
|
|
|
# 通道配置
|
|
|
|
|
self.channels = list(range(1, 9))
|
|
|
|
|
self.channel_vars = {}
|
|
|
|
|
self.channel_colors = plt.cm.Set1(np.linspace(0, 1, 8))
|
|
|
|
|
|
|
|
|
|
# 当前选中的通道
|
|
|
|
|
self.selected_channel = tk.IntVar(value=1) # 默认选择通道1
|
|
|
|
|
self.previous_channel = 1 # 记录上一个通道
|
|
|
|
|
|
|
|
|
|
# 现在调用父类构造函数
|
|
|
|
|
super().__init__(parent, tcp_client, "实时波形")
|
|
|
|
|
|
|
|
|
|
@ -59,16 +62,22 @@ class WaveformPage(BasePage):
|
|
|
|
|
channel_frame = ttk.Frame(control_frame)
|
|
|
|
|
channel_frame.pack(fill=tk.X, pady=5)
|
|
|
|
|
|
|
|
|
|
ttk.Label(channel_frame, text="通道选择:").pack(side=tk.LEFT)
|
|
|
|
|
ttk.Label(channel_frame, text="通道选择:").pack(side=tk.LEFT, padx=(0, 10))
|
|
|
|
|
|
|
|
|
|
# 创建通道选择下拉框
|
|
|
|
|
channel_combo = ttk.Combobox(channel_frame,
|
|
|
|
|
textvariable=self.selected_channel,
|
|
|
|
|
values=self.channels,
|
|
|
|
|
state="readonly",
|
|
|
|
|
width=10)
|
|
|
|
|
channel_combo.pack(side=tk.LEFT, padx=5)
|
|
|
|
|
|
|
|
|
|
# 创建8个通道的复选框
|
|
|
|
|
for i, channel in enumerate(self.channels):
|
|
|
|
|
var = tk.BooleanVar(value=True)
|
|
|
|
|
self.channel_vars[channel] = var
|
|
|
|
|
# 绑定选择事件
|
|
|
|
|
channel_combo.bind('<<ComboboxSelected>>', self.on_channel_selected)
|
|
|
|
|
|
|
|
|
|
check = ttk.Checkbutton(channel_frame, text=f"通道{channel}",
|
|
|
|
|
variable=var, command=self.update_plot)
|
|
|
|
|
check.pack(side=tk.LEFT, padx=5)
|
|
|
|
|
# 通道信息显示
|
|
|
|
|
self.channel_info_var = tk.StringVar(value="当前通道: 1")
|
|
|
|
|
ttk.Label(channel_frame, textvariable=self.channel_info_var).pack(side=tk.LEFT, padx=(20, 0))
|
|
|
|
|
|
|
|
|
|
# 控制按钮
|
|
|
|
|
button_frame = ttk.Frame(control_frame)
|
|
|
|
|
@ -92,6 +101,37 @@ class WaveformPage(BasePage):
|
|
|
|
|
self.setup_plot(plot_frame)
|
|
|
|
|
self.setup_udp()
|
|
|
|
|
|
|
|
|
|
def on_channel_selected(self, event=None):
|
|
|
|
|
"""通道选择变化时的回调函数"""
|
|
|
|
|
new_channel = self.selected_channel.get()
|
|
|
|
|
|
|
|
|
|
# 检查是否真的切换了通道
|
|
|
|
|
if new_channel != self.previous_channel:
|
|
|
|
|
print(f"切换通道: {self.previous_channel} -> {new_channel}")
|
|
|
|
|
|
|
|
|
|
# 清空当前显示的数据
|
|
|
|
|
self.clear_display_data()
|
|
|
|
|
|
|
|
|
|
# 更新通道信息
|
|
|
|
|
self.channel_info_var.set(f"当前通道: {new_channel}")
|
|
|
|
|
|
|
|
|
|
# 更新上一个通道记录
|
|
|
|
|
self.previous_channel = new_channel
|
|
|
|
|
|
|
|
|
|
# 更新显示
|
|
|
|
|
self.update_plot()
|
|
|
|
|
|
|
|
|
|
def clear_display_data(self):
|
|
|
|
|
"""清空显示数据(但不停止UDP接收)"""
|
|
|
|
|
# 清空当前显示的波形数据
|
|
|
|
|
self.line.set_data([], [])
|
|
|
|
|
|
|
|
|
|
# 重绘画布
|
|
|
|
|
self.canvas.draw_idle()
|
|
|
|
|
|
|
|
|
|
# 更新状态显示
|
|
|
|
|
self.status_var.set(f"已切换到通道 {self.selected_channel.get()}")
|
|
|
|
|
|
|
|
|
|
def setup_plot(self, parent):
|
|
|
|
|
"""设置波形图"""
|
|
|
|
|
# 创建图形和坐标轴
|
|
|
|
|
@ -133,14 +173,11 @@ class WaveformPage(BasePage):
|
|
|
|
|
self.canvas.draw()
|
|
|
|
|
self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
|
|
|
|
|
|
|
|
|
|
# 初始化线条对象
|
|
|
|
|
self.lines = {}
|
|
|
|
|
for channel in self.channels:
|
|
|
|
|
line, = self.ax.plot([], [],
|
|
|
|
|
color=self.channel_colors[channel - 1],
|
|
|
|
|
# 初始化线条对象 - 现在只需要一个线条,因为每次只显示一个通道
|
|
|
|
|
self.line, = self.ax.plot([], [],
|
|
|
|
|
color=self.channel_colors[0], # 使用第一个颜色
|
|
|
|
|
linewidth=1,
|
|
|
|
|
label=f'通道{channel}')
|
|
|
|
|
self.lines[channel] = line
|
|
|
|
|
label='波形数据')
|
|
|
|
|
|
|
|
|
|
# 添加图例
|
|
|
|
|
self.ax.legend(loc='upper right')
|
|
|
|
|
@ -208,7 +245,6 @@ class WaveformPage(BasePage):
|
|
|
|
|
try:
|
|
|
|
|
data, addr = self.udp_socket.recvfrom(65536) # 最大接收64KB
|
|
|
|
|
print(f"接收到来自 {addr} 的数据:")
|
|
|
|
|
print(f"原始数据: {data}")
|
|
|
|
|
print(f"数据长度: {len(data)} 字节")
|
|
|
|
|
buffer += data
|
|
|
|
|
|
|
|
|
|
@ -271,7 +307,9 @@ class WaveformPage(BasePage):
|
|
|
|
|
# 根据当前的纵轴配置 self.y_min 和 self.y_max
|
|
|
|
|
waveform_mv = np.clip(waveform_mv, self.y_min, self.y_max)
|
|
|
|
|
|
|
|
|
|
# 9. 更新数据
|
|
|
|
|
# 9. 更新数据(只更新当前选中通道的数据)
|
|
|
|
|
current_channel = self.selected_channel.get()
|
|
|
|
|
if channel_id == current_channel:
|
|
|
|
|
self.waveform_data[channel_id] = waveform_mv
|
|
|
|
|
self.latest_timestamps[channel_id] = (century_second, nanosecond)
|
|
|
|
|
|
|
|
|
|
@ -282,7 +320,8 @@ class WaveformPage(BasePage):
|
|
|
|
|
print(f"波形数据点数: {len(waveform_data)}")
|
|
|
|
|
print(f"数据范围: {np.min(waveform_data)} ~ {np.max(waveform_data)} mV")
|
|
|
|
|
|
|
|
|
|
# 11. 更新显示
|
|
|
|
|
# 11. 更新显示(只有当前选中通道的数据才显示)
|
|
|
|
|
if channel_id == current_channel:
|
|
|
|
|
self.update_plot()
|
|
|
|
|
|
|
|
|
|
# 12. 从缓冲区移除已处理的数据
|
|
|
|
|
@ -301,24 +340,48 @@ class WaveformPage(BasePage):
|
|
|
|
|
if not hasattr(self, 'ax'):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 清除之前的线条数据
|
|
|
|
|
for channel in self.channels:
|
|
|
|
|
self.lines[channel].set_data([], [])
|
|
|
|
|
# 获取当前选中的通道
|
|
|
|
|
selected_channel = self.selected_channel.get()
|
|
|
|
|
|
|
|
|
|
# 清空线条数据
|
|
|
|
|
self.line.set_data([], [])
|
|
|
|
|
|
|
|
|
|
# 更新选中的通道数据
|
|
|
|
|
# 更新选中通道的数据
|
|
|
|
|
has_data = False
|
|
|
|
|
for channel in self.channels:
|
|
|
|
|
if (self.channel_vars[channel].get() and
|
|
|
|
|
channel in self.waveform_data and
|
|
|
|
|
len(self.waveform_data[channel]) == self.sample_points):
|
|
|
|
|
waveform = self.waveform_data[channel]
|
|
|
|
|
self.lines[channel].set_data(self.time_axis, waveform)
|
|
|
|
|
if (selected_channel in self.waveform_data and
|
|
|
|
|
len(self.waveform_data[selected_channel]) > 0):
|
|
|
|
|
|
|
|
|
|
waveform = self.waveform_data[selected_channel]
|
|
|
|
|
|
|
|
|
|
# 根据实际数据点数创建时间轴
|
|
|
|
|
actual_points = len(waveform)
|
|
|
|
|
if actual_points == self.sample_points:
|
|
|
|
|
time_axis = self.time_axis
|
|
|
|
|
else:
|
|
|
|
|
time_axis = np.linspace(0, self.sample_duration, actual_points)
|
|
|
|
|
|
|
|
|
|
# 更新线条数据和颜色
|
|
|
|
|
self.line.set_data(time_axis, waveform)
|
|
|
|
|
self.line.set_color(self.channel_colors[selected_channel - 1])
|
|
|
|
|
self.line.set_label(f'通道{selected_channel}')
|
|
|
|
|
|
|
|
|
|
has_data = True
|
|
|
|
|
|
|
|
|
|
# 更新通道信息显示
|
|
|
|
|
if selected_channel in self.latest_timestamps:
|
|
|
|
|
century_second, nanosecond = self.latest_timestamps[selected_channel]
|
|
|
|
|
self.channel_info_var.set(f"当前通道: {selected_channel} - 时间: {century_second}.{nanosecond:09d}")
|
|
|
|
|
|
|
|
|
|
# 如果有数据显示,更新图形
|
|
|
|
|
if has_data:
|
|
|
|
|
self.ax.relim()
|
|
|
|
|
self.ax.autoscale_view()
|
|
|
|
|
# 更新图例
|
|
|
|
|
self.ax.legend(loc='upper right')
|
|
|
|
|
self.canvas.draw_idle()
|
|
|
|
|
else:
|
|
|
|
|
# 没有数据时显示提示
|
|
|
|
|
self.channel_info_var.set(f"当前通道: {selected_channel} - 无数据")
|
|
|
|
|
self.canvas.draw_idle()
|
|
|
|
|
|
|
|
|
|
def auto_scale(self):
|
|
|
|
|
@ -329,11 +392,11 @@ class WaveformPage(BasePage):
|
|
|
|
|
self.canvas.draw_idle()
|
|
|
|
|
|
|
|
|
|
def clear_data(self):
|
|
|
|
|
"""清空波形数据"""
|
|
|
|
|
"""清空所有通道的数据"""
|
|
|
|
|
self.waveform_data.clear()
|
|
|
|
|
self.latest_timestamps.clear()
|
|
|
|
|
self.update_plot()
|
|
|
|
|
self.status_var.set("数据已清空")
|
|
|
|
|
self.clear_display_data()
|
|
|
|
|
self.status_var.set("所有通道数据已清空")
|
|
|
|
|
|
|
|
|
|
def get_channel_info(self, channel_id):
|
|
|
|
|
"""获取通道信息字符串"""
|
|
|
|
|
@ -359,9 +422,7 @@ class WaveformPage(BasePage):
|
|
|
|
|
return int_ip
|
|
|
|
|
|
|
|
|
|
def ipv4_to_int(self, ipv4_address):
|
|
|
|
|
|
|
|
|
|
packed_ip = socket.inet_aton(ipv4_address)
|
|
|
|
|
|
|
|
|
|
return struct.unpack("!L", packed_ip)[0]
|
|
|
|
|
|
|
|
|
|
def get_local_ip(self):
|
|
|
|
|
|