You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击按钮实时写入串口数据到CSV失败,求修复方法

问题修复方案

你的代码存在几个核心问题,导致串口数据无法写入CSV,还会引发UI卡死,以下是具体修复步骤和代码实现:

核心问题分析

  1. 死循环阻塞Qt事件循环:按钮点击事件里的while True会直接占用Qt主线程,导致UI完全无响应,串口读取逻辑也无法正常执行(主线程被卡死,无法处理串口输入事件)。
  2. 文件缓冲区未实时刷新:默认文件流会缓存数据,不会立刻写入磁盘,看起来像是没有写入操作。
  3. 无停止逻辑:一旦启动写入就无法主动停止,只能强制关闭程序。

修复后的代码实现

第一步:在类初始化中添加状态变量

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:27:35