重新实现 QSerialPort canReadLine() 和 readLine() 方法

Posted

技术标签:

【中文标题】重新实现 QSerialPort canReadLine() 和 readLine() 方法【英文标题】:Reimplementing QSerialPort canReadLine() and readLine() methods 【发布时间】:2021-06-01 08:22:07 【问题描述】:

我正在尝试通过 QSerialPort 接收自定义帧原始字节,使用值 0 作为异步模式下的分隔符(使用信号而不是轮询)。

不便之处在于 QSerialPort 似乎没有一种方法可以读取串行数据,直到遇到指定的字节值,例如pyserial 中的 read_until (delimiter_value)。

我想知道是否可以在 Python 中重新实现 QSerialPort 的 readLine() 函数,以便它读取直到遇到 0 字节值而不是 '\n'。同样,重新实现 canReadLine() 也会很方便。

我知道可以使用 readAll() 方法,然后解析数据以获取分隔符值。但是这种方法可能意味着更多的代码和效率的降低。我希望在处理帧时开销尽可能低(串行波特率和传入字节数很大)。但是,如果您知道一种快速的方法,我想看看。

【问题讨论】:

【参考方案1】:

我最终解析了框架,它似乎工作得很好。 下面是从我的脚本中提取的一个方法,它异步接收和解析串行数据。 self.serial_buffer 是在自定义类 init 方法中初始化的 QByteArray 数组。您也可以使用全局声明的字节数组,但您必须以另一种方式检查您的分隔符值。

@pyqtSlot()
def receive(self):
    self.serial_buffer += self.serial.readAll()   # Read all data from serial buffer

    start_pos, del_pos = 0, 0
    while True:
        del_pos = self.serial_buffer.indexOf(b'\x00', start_pos)   # b'\x00' is delimiter byte
        if del_pos == -1: break   # del_pos is -1 if b'\x00' is not found
        frame = self.serial_buffer[start_pos: del_pos]   # Copy data until delimiter
        start_pos = del_pos + 1   # Exclude old delimiter from your search
        self.serial_buffer = self.serial_buffer[start_pos:]   # Copy remaining data excluding frame
        self.process_frame(frame)   # Process frame

【讨论】:

以上是关于重新实现 QSerialPort canReadLine() 和 readLine() 方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Ubuntu 中使用 QSerialport 时遇到问题

使用 Linux 伪终端测试 QSerialPort

QSerialPort 不一致的行为取决于起始波特率

Qt Widget 之简易串口助手(QSerialPort)

Qt Widget 之简易串口助手(QSerialPort)

如何知道 QSerialPort 何时准备好接收 Qt5 中的更多数据?