[update] 优化界面及记录的处理

- 修改数据记录数量的显示\n-修改了记录的存储位置,存储到./records文件夹\n
This commit is contained in:
JingweiCui 2025-01-10 22:54:25 +08:00
parent f7a4a23ab8
commit a7f6220682
5 changed files with 142 additions and 13 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
__pycache__ __pycache__
build build
dist dist
*.dat *.dat
records

View File

@ -28,6 +28,8 @@ class Frame:
for byte in data: for byte in data:
chksum += byte chksum += byte
return chksum & 0xFF return chksum & 0xFF
def extract_frame(self, frame_data): def extract_frame(self, frame_data):
"""提取数据帧""" """提取数据帧"""
@ -76,6 +78,13 @@ class SerialDataLogger(QObject):
self.process_thread.daemon = True self.process_thread.daemon = True
self.process_thread.start() self.process_thread.start()
def set_channels(self, channel_num):
"""设置通道数
Args:
channels (int): 通道数量
"""
self.CH_NUM = channel_num
def set_port(self, port, baudrate): def set_port(self, port, baudrate):
self.port = port self.port = port
self.baudrate = baudrate self.baudrate = baudrate
@ -95,8 +104,8 @@ class SerialDataLogger(QObject):
try: try:
if not self.is_running and self.process_queue.empty(): if not self.is_running and self.process_queue.empty():
continue continue
# 从队列中获取数据,设置1秒超时 # 从队列中获取数据,设置0.1秒超时
data = self.process_queue.get(timeout=1) data = self.process_queue.get(timeout=0.1)
# print('process_thread_func processing') # print('process_thread_func processing')
self.process_buffer(data) self.process_buffer(data)
self.signal_some_frames_processed.emit(self.recorded_frames_count) self.signal_some_frames_processed.emit(self.recorded_frames_count)
@ -241,7 +250,7 @@ class SerialDataLogger(QObject):
self.recorded_frames_count = 0 self.recorded_frames_count = 0
# 当前时间格式化为本地时间 # 当前时间格式化为本地时间
formatted = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime()) formatted = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime())
self.output_file = f"serial_data_{formatted}.dat" self.output_file = f"./records/signal_record_{formatted}.dat"
return True return True
except Exception as e: except Exception as e:
print(f"启动失败: {e}") print(f"启动失败: {e}")
@ -253,10 +262,12 @@ class SerialDataLogger(QObject):
try: try:
# 先设置停止标志 # 先设置停止标志
self.is_running = False self.is_running = False
# 等待采集线程结束 # 等待采集线程结束
if self.collect_thread and self.collect_thread.is_alive(): if self.collect_thread and self.collect_thread.is_alive():
self.collect_thread.join(timeout=2.0) self.collect_thread.join(timeout=0.1)
# 确保串口仍然打开时才处理剩余数据 # 确保串口仍然打开时才处理剩余数据
if self.ser and self.ser.is_open: if self.ser and self.ser.is_open:
@ -266,10 +277,11 @@ class SerialDataLogger(QObject):
self.buffer.clear() self.buffer.clear()
# 等待处理队列清空 # 等待处理队列清空
timeout = time.time() + 2.0 while not self.process_queue.empty():
while not self.process_queue.empty() and time.time() < timeout:
time.sleep(0.1) time.sleep(0.1)
print('stop !')
return True return True
except Exception as e: except Exception as e:

View File

@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='data_collector_v1.0.5',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

50
main.py
View File

@ -6,13 +6,14 @@ from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from PySide6.QtGui import QIntValidator from PySide6.QtGui import QIntValidator
from data_collector import SerialDataLogger from data_collector import SerialDataLogger
import os
class SerialUI(QMainWindow): class SerialUI(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.setWindowTitle("Data Colllector 24CH V1.0.4") self.setWindowTitle("Signal Collector V1.0.5")
self.resize(400, 200) self.resize(400, 300)
# 设置应用样式 # 设置应用样式
self.setStyleSheet(""" self.setStyleSheet("""
@ -132,6 +133,16 @@ class SerialUI(QMainWindow):
record_layout.addWidget(self.record_btn) record_layout.addWidget(self.record_btn)
layout.addLayout(record_layout) layout.addLayout(record_layout)
channel_layout = QHBoxLayout()
self.channel_input = QLineEdit()
self.channel_input.setText("0") # 设置默认值为0
self.channel_input.setPlaceholderText("输入标签内容")
self.set_channel_btn = QPushButton("设置通道")
self.set_channel_btn.clicked.connect(self.confirm_channel_setting)
channel_layout.addWidget(self.channel_input)
channel_layout.addWidget(self.set_channel_btn)
layout.addLayout(channel_layout)
# 标签输入区域 # 标签输入区域
tag_layout = QHBoxLayout() tag_layout = QHBoxLayout()
self.tag_input = QLineEdit() self.tag_input = QLineEdit()
@ -145,9 +156,13 @@ class SerialUI(QMainWindow):
# 数据计数显示区域 # 数据计数显示区域
count_layout = QHBoxLayout() count_layout = QHBoxLayout()
self.count_label = QLabel("当前记录数量:0") self.count_label = QLabel("当前记录数量:")
self.count_label.setAlignment(Qt.AlignCenter) self.count_label.setAlignment(Qt.AlignCenter)
count_layout.addWidget(self.count_label) count_layout.addWidget(self.count_label)
self.count_value_label = QLabel("0")
self.count_value_label.setAlignment(Qt.AlignCenter)
count_layout.addWidget(self.count_value_label)
layout.addLayout(count_layout) layout.addLayout(count_layout)
# 添加状态栏 # 添加状态栏
@ -177,7 +192,13 @@ class SerialUI(QMainWindow):
# 初始化时禁用录制按钮 # 初始化时禁用录制按钮
self.record_btn.setEnabled(False) self.record_btn.setEnabled(False)
records_save_path = './records'
if not os.path.exists(records_save_path):
# 如果不存在,则创建文件夹
os.makedirs(records_save_path)
self.serial_logger = SerialDataLogger() self.serial_logger = SerialDataLogger()
self.channel_input.setText(str(self.serial_logger.CH_NUM))
self.serial_logger.signal_some_frames_processed.connect(self.update_count_display) self.serial_logger.signal_some_frames_processed.connect(self.update_count_display)
# 添加退出时的确认标志 # 添加退出时的确认标志
@ -187,7 +208,7 @@ class SerialUI(QMainWindow):
"""更新数据计数显示""" """更新数据计数显示"""
if self.serial_logger: if self.serial_logger:
count = self.serial_logger.recorded_frames_count count = self.serial_logger.recorded_frames_count
self.count_label.setText(f"当前记录数量:{count}") self.count_value_label.setText(str(count))
def get_recorder_tag(self): def get_recorder_tag(self):
return self.label_input.text() return self.label_input.text()
@ -208,6 +229,24 @@ class SerialUI(QMainWindow):
self.port_combo.addItem(port_info, port.device) self.port_combo.addItem(port_info, port.device)
else: else:
self.statusBar().showMessage("未找到可用串口") self.statusBar().showMessage("未找到可用串口")
def confirm_channel_setting(self):
"""确认通道数设置"""
try:
channels = int(self.channel_input.text())
if 1 <= channels <= 64:
if self.serial_logger:
self.serial_logger.set_channels(channels)
self.statusBar().showMessage(f"已设置通道数: {channels}")
# 禁用通道设置
self.channel_input.setEnabled(False)
self.set_channel_btn.setEnabled(False)
# 启用录制按钮
self.record_btn.setEnabled(True)
else:
QMessageBox.warning(self, "警告", "请输入1-64之间的通道数")
except ValueError:
QMessageBox.warning(self, "警告", "请输入有效的通道数")
def toggle_connection(self): def toggle_connection(self):
"""切换端口连接状态""" """切换端口连接状态"""
@ -268,9 +307,10 @@ class SerialUI(QMainWindow):
return return
if self.record_btn.isChecked(): if self.record_btn.isChecked():
print('start recording')
self.serial_logger.test_connection() self.serial_logger.test_connection()
if self.serial_logger.start(): if self.serial_logger.start():
count = self.serial_logger.recorded_frames_count
self.count_value_label.setText(str(count))
self.record_btn.setText("停止录制") self.record_btn.setText("停止录制")
self.statusBar().showMessage("正在录制...") self.statusBar().showMessage("正在录制...")
# 禁用连接按钮 # 禁用连接按钮

View File

@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='signal_collector_v1.0.5',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)