readAll() from QSerialPort doesn#39;t include the last response sent(来自 QSerialPort 的 readAll() 不包括最后发送的响应)
问题描述
我正在使用 Qt 来控制串行设备.如果我向串行设备发送命令,我会执行 serial->write("command
")
之类的操作.我做了一个按钮,它将纯文本小部件内的文本更改为串行端口的响应.为了得到串口的响应,我使用了serial->readAll()
.问题是它显示了倒数第二个响应,而不是我期望的响应.Qt 是否有某种缓冲区来保存此响应?
I'm using Qt to control a serial device. If I send a command to my serial device, I do something like serial->write("command
")
. I made a push button which changes the text inside a plain text widget to the response of the serial port. To get the response of the serial port, I'm using serial->readAll()
. The problem is it shows the 2nd to last response rather than the one I was expecting. Does Qt have some sort of buffer which is keeping hold of this response?
编辑我使用递归搞砸了它并比较了收到的字符串
EDIT I botched it by using recursion and compared the strings recieved
推荐答案
您可能在响应可用之前调用了 readAll
.您应该将代码挂接到 readyRead
信号,以便在每次准备好读取新数据块时收到通知.请记住,readyRead
可以发出任意数量的可供读取的字节 - 至少只有一个字节.您不能期望数据以任何特定方式被分块/阻塞,因为串行端口不充当基于消息的通信设备.您的接收器代码必须能够将数据从小块拼凑在一起,并在获得所需的所有数据时采取相应的行动.
You might be calling readAll
before the response is available. You should hook your code to the readyRead
signal to be notified each time new chunk of data is ready to be read. Keep in mind that readyRead
can be emitted with any number of bytes available to read - at a minimum, it'll be just one byte. You can't expect the data to be chunked/blocked in any particular way, since the serial port doesn't act as a message-based communication device. Your receiver code must be able to piece the data together from small chunks and act accordingly when it got all the data it needs.
例如,假设设备响应具有固定的已知长度.您只想在完整响应到达时做出反应.例如:
For example, suppose that the device responses have a fixed, known length. You'd only want to react when a complete response has arrived. E.g.:
class Protocol : public QObject {
Q_OBJECT
QBasicTimer m_timer;
QPointer<QIODevice> m_port;
int m_responseLength = 0;
int m_read = 0;
void timerEvent(QTimerEvent * ev) override {
if (ev->timerId() != m_timer.timerId()) return;
m_timer.stop();
emit timedOut();
}
void onData() {
m_read += m_port->bytesAvailable();
if (m_read < m_responseLength)
return;
m_timer.stop();
emit gotResponse(m_port->read(m_responseLength));
m_read -= m_responseLength;
m_responseLength = 0;
}
public:
Q_SIGNAL void gotResponse(const QByteArray &);
Q_SIGNAL void timedOut();
Q_SLOT void sendCommand(const QByteArray & cmd, int responseLength, int cmdTimeout) {
m_responseLength = responseLength;
m_port->write(cmd);
m_timer.start(cmdTimeout, this);
}
explicit Protocol(QIODevice * port, QObject * parent = nullptr) :
QObject(parent), m_port(port) {
connect(m_port, &QIODevice::readyRead, this, &Protocol::onData);
}
};
...
Protocol protocol(0,0);
protocol.sendCommand({"foo"}, 10, 500);
QMetaObject::Connection cmd1;
cmd1 = QObject::connect(&protocol, &Protocol::gotResponse, [&]{
QObject::disconnect(cmd1);
qDebug() << "got response to foo";
});
QObject::connect(&protocol, &Protocol::timedOut, []{ qDebug() << "timed out :("; });
这篇关于来自 QSerialPort 的 readAll() 不包括最后发送的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:来自 QSerialPort 的 readAll() 不包括最后发送的响应
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01