加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – readyRead()在Qt中如何工作?

发布时间:2020-12-16 10:10:36 所属栏目:百科 来源:网络整理
导读:这是我在这个网站上的第一个问题! 我在从COM端口读取数据时遇到一些麻烦,我从另一个COM端口发送完整的消息,当我用Qt接收它时,它总是被切成多个子消息. void SerialPortReader::init(){ connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(readData()));}
这是我在这个网站上的第一个问题!

我在从COM端口读取数据时遇到一些麻烦,我从另一个COM端口发送完整的消息,当我用Qt接收它时,它总是被切成多个子消息.

void SerialPortReader::init()
{
    connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(readData()));
}   

void SerialPortReader::readData()
{
//    m_serialPort->waitForReadyRead(200);
    QByteArray byteArray = m_serialPort->readAll();
    qDebug() << byteArray;

    if(byteArray.startsWith(SOF) && byteArray.endsWith(EOF_LS)
        && byteArray.size() >= MIN_SIZE_DATA) {
    decodeData(byteArray.constData());
    } else {
        qDebug() << "LIB SWCom : Unvalid trame !";
    }
}

发送的消息长度为25或27字节,如果我使用Putty或Hyperterminal来读取它们,我没有遇到麻烦.
另外如果我使用2个模拟串口COM进行通信,我没有这个问题……
它只发生在Qt读取系统和2个物理COM端口……

我认为在准确发出readyRead信号时我没有得到…

我很困惑,提前谢谢你的帮助!

解决方法

documentation实际上非常清楚:

void QIODevice::readyRead() [signal]

This signal is emitted once every time new data is available for reading from the device. It will only be emitted again once new data is available,such as when a new payload of network data has arrived on your network socket,or when a new block of data has been appended to your device.

readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal,the signal will not be reemitted (although waitForReadyRead() may still return true).

Note for developers implementing classes derived from QIODevice: you should always emit readyRead() when new data has arrived (do not emit it only because there’s data still to be read in your buffers). Do not emit readyRead() in other conditions.

这意味着它并没有真正保证可以读取多少数据,只是有些数据可用.

如果您希望读取的数据多于一次性输入的数据,则可以选择超时值和/或readyRead.这取决于你想要达到的目标.

请参阅我之前为此操作编写的command line async reader example:

#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,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);
    }
}

在这种情况下,命令行阅读器示例将获取一次性传递的任何数据,但不保证长度或任何内容.

此外,请注意您的评论背后的同步api与您询问的异步API一起没有多大意义.我指的是m_serialPort-> waitForReadyRead(200);在这里.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读