ドキュメントは実際にはそれについて非常に明確です:
void QIODevice::readyRead() [シグナル]
このシグナルは、デバイスからの読み取りに新しいデータが使用可能になるたびに 1 回発行されます。ネットワークデータの新しいペイロードがネットワークソケットに到着したとき、またはデータの新しいブロックがデバイスに追加されたときなど、新しいデータが利用可能になったときにのみ再度送信されます。
readyRead() は再帰的に発行されません。イベント ループに再度入るか、readyRead() シグナルに接続されたスロット内で waitForReadyRead() を呼び出すと、シグナルは再送信されません (ただし、waitForReadyRead() は true を返す場合があります)。
QIODevice から派生したクラスを実装する開発者への注意: 新しいデータが到着したときは常に readyRead() を発行する必要があります (バッファにまだ読み取るデータがあるという理由だけで発行しないでください)。他の条件で readyRead() を発行しないでください。
これは、読み取りに使用できるデータの量が実際に保証されているわけではなく、一部が使用可能であることを意味します。
一度に送信されるよりも多くのデータを読み取りたい場合は、タイムアウト値および/または readyRead を選択できます。それはあなたが何を達成しようとしているかによって異なります。
この操作については、私が少し前に書いたコマンド ライン非同期リーダーの例も参照してください。
#include "serialportreader.h"
#include <QCoreApplication>
QT_USE_NAMESPACE
SerialPortReader::SerialPortReader(QSerialPort *serialPort, QObject *parent)
: QObject(parent)
, m_serialPort(serialPort)
, m_standardOutput(stdout)
{
connect(m_serialPort, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError)));
connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
m_timer.start(5000);
}
SerialPortReader::~SerialPortReader()
{
}
void SerialPortReader::handleReadyRead()
{
m_readData.append(m_serialPort->readAll());
if (!m_timer.isActive())
m_timer.start(5000);
}
void SerialPortReader::handleTimeout()
{
if (m_readData.isEmpty()) {
m_standardOutput << QObject::tr("No data was currently available for reading from port %1").arg(m_serialPort->portName()) << endl;
} else {
m_standardOutput << QObject::tr("Data successfully received from port %1").arg(m_serialPort->portName()) << endl;
m_standardOutput << m_readData << endl;
}
QCoreApplication::quit();
}
void SerialPortReader::handleError(QSerialPort::SerialPortError serialPortError)
{
if (serialPortError == QSerialPort::ReadError) {
m_standardOutput << QObject::tr("An I/O error occurred while reading the data from port %1, error: %2").arg(m_serialPort->portName()).arg(m_serialPort->errorString()) << endl;
QCoreApplication::exit(1);
}
}
この場合、コマンド ライン リーダーの例では、渡されたすべてのデータが 1 回で取得されますが、長さなどは保証されません。
また、コメントの背後にある同期APIは、あなたが求めている非同期APIと一緒に意味をなさないことに注意してください. 私はm_serialPort->waitForReadyRead(200);
ここで言及しています。