0

在 Qt 5.1 中,我遇到了 QXMLStreamReader 等待 QProcess 生成更多数据的问题。

如果我从无缓冲的 QProcess 中读取行,它可以正常工作:

while(!vupProcess.state() == QProcess::NotRunning)
{
    if (vupProcess.atEnd())
    {
        vupProcess.waitForReadyRead();
    }
    qDebug() << vupProcess.readLine();
}

非常明确:当缓冲区没有数据时,它会等到有更多数据。当有更多时,它将打印行而不等待。

现在,如果我想对 QXMLStreamReader 做同样的事情,它可以工作,但是 XML 元素的处理发生在错误的时刻(为时已晚)。

考虑一下:

QXmlStreamReader xml;
xml.setDevice(&vupProcess);
QStack<VUPDevice *> deviceStack;
QXmlStreamReader::TokenType tokenType = QXmlStreamReader::NoToken;

while (tokenType != QXmlStreamReader::EndDocument && !xml.hasError())
{
    if (xml.device()->atEnd())
    {
        xml.device()->waitForReadyRead(XML_READNEXT_TIMEOUT);
    }

    tokenType = xml.readNext();

    if (xml.hasError())
    {
        qDebug() << "ERROR";
        return;
    }

    ...
}

waitForReadyRead(int)调用的时候,很多元素已经可用,我需要对它们进行处理以更新 GUI。但是,在 QProcess 开始输出more之前它不会继续。这似乎是因为底层 QProcess 被尽可能快地读取直到它为空,然后我的解析器在早期阶段不必要地挂起,因为 QProcess 不再输出。

我需要的是xml.hasMoreElements(),以便我可以制作:

if (xml.device()->atEnd() && !xml.hasMoreElements())
{
    xml.device()->waitForReadyRead(XML_READNEXT_TIMEOUT);
}

但我似乎找不到为我执行此操作的 API 调用。

那么,当不需要时,我如何不等待更多数据呢?

4

1 回答 1

2

我想我解决了。没有办法询问是否还有更多 XML 元素,但readNext()调用会将QXMLStreamReader对象置于您可以检测到的状态,并用于让后端设备等待:

QXmlStreamReader::TokenType tokenType = xml.readNext();

while (xml.error() == QXmlStreamReader::PrematureEndOfDocumentError)
{
    xml.device()->waitForReadyRead(XML_READNEXT_TIMEOUT);
    tokenType = xml.readNext();
}

if (xml.hasError())
{
    ...
}
于 2013-12-02T19:45:25.233 回答