点击按钮实时写入串口数据到CSV失败,求修复方法
问题修复方案
你的代码存在几个核心问题,导致串口数据无法写入CSV,还会引发UI卡死,以下是具体修复步骤和代码实现:
核心问题分析
- 死循环阻塞Qt事件循环:按钮点击事件里的
while True会直接占用Qt主线程,导致UI完全无响应,串口读取逻辑也无法正常执行(主线程被卡死,无法处理串口输入事件)。 - 文件缓冲区未实时刷新:默认文件流会缓存数据,不会立刻写入磁盘,看起来像是没有写入操作。
- 无停止逻辑:一旦启动写入就无法主动停止,只能强制关闭程序。
修复后的代码实现
第一步:在类初始化中添加状态变量
def __init__(self): # 保留你原有的初始化代码 self.is_writing = False # 标记是否正在写入CSV self.csv_file = None # 保存文件句柄 self.csv_writer = None # 保存CSV写入器 self.timer = None # 定时器用于非阻塞读取串口
第二步:修改按钮点击事件函数
def on_searchfile_clicked(self): # 切换状态:如果正在写入则停止,否则开始 if self.is_writing: self.is_writing = False self.timer.stop() if self.csv_file: self.csv_file.close() self.csv_file = None self.csv_writer = None self.pushBtn.setText("开始记录") # 按钮文本切换为开始 return # 选择CSV保存路径 file_path, _ = QFileDialog.getSaveFileName(self, "保存CSV文件", './', "CSV file (*.csv)") if not file_path: return # 打开文件并初始化写入器 try: self.csv_file = open(file_path, 'a', encoding='utf-8', newline='') self.csv_writer = csv.writer(self.csv_file) self.csv_writer.writerow(['Num']) # 写入表头 self.is_writing = True self.pushBtn.setText("停止记录") # 按钮文本切换为停止 # 启动定时器,每隔10ms检查一次串口数据(可根据需求调整间隔) self.timer = QTimer(self) self.timer.timeout.connect(self.read_serial_write_csv) self.timer.start(10) except Exception as e: print(f"文件打开失败: {str(e)}") self.is_writing = False
第三步:添加串口读取与CSV写入函数
def read_serial_write_csv(self): if not self.is_writing or not self.csv_writer: self.timer.stop() return try: # 非阻塞读取:先检查串口缓冲区是否有数据 if ser.in_waiting > 0: data = ser.readline().decode().strip() if data: # 过滤空数据 self.csv_writer.writerow([data]) self.csv_file.flush() # 强制刷新缓冲区,确保数据实时写入磁盘 except Exception as e: print(f"读写出错: {str(e)}") # 出错时自动停止写入 self.is_writing = False self.timer.stop() if self.csv_file: self.csv_file.close() self.pushBtn.setText("开始记录")
额外注意事项
- 检查串口状态:确保全局变量
ser已经正确调用ser.open()打开,且串口参数(波特率、数据位、停止位、奇偶校验)与发送端完全一致。 - 串口占用问题:确认没有其他程序占用该串口,否则会导致读取失败。
- 定时器间隔:可根据串口数据的发送频率调整定时器的
start()参数(单位:毫秒),避免过于频繁检查浪费资源。
内容的提问来源于stack exchange,提问作者heartin
相关产品推荐
相关产品推荐

