Sie erhielt im Vergleich könnte readAll
, bevor die Antwort zur Verfügung anrufen. Sie sollten Ihren Code an das readyRead
Signal anhängen, um jedes Mal benachrichtigt zu werden, wenn ein neuer Datenblock zum Lesen bereit ist. Denken Sie daran, dass readyRead
mit einer beliebigen Anzahl von Bytes zum Lesen ausgegeben werden kann - mindestens wird es nur ein Byte sein. Sie können nicht erwarten, dass die Daten in einer bestimmten Weise chunked/blockiert werden, da der serielle Port nicht als nachrichtenbasiertes Kommunikationsgerät fungiert. Ihr Empfängercode muss in der Lage sein, die Daten aus kleinen Teilen zusammenzusetzen und entsprechend zu handeln, wenn alle benötigten Daten vorhanden sind.
Angenommen, die Antworten des Geräts haben eine feste, bekannte Länge. Sie möchten nur reagieren, wenn eine vollständige Antwort eingetroffen ist. Zum Beispiel:
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 :("; });
Danke das war eine sehr hilfreiche Antwort! – jxb458