QXMLStreamreader从慢速QProcess读取

时间:2013-12-02 15:19:08

标签: qt qxmlstreamreader

在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开始输出更多之前,它不会继续。这似乎是因为底层QProcess被读取,直到它尽可能快地为空,然后我的解析器在早期阶段不必要地挂起,因为QProcess不再输出。

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

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

但我似乎无法找到为我这样做的API调用。

那么,如果不是必要的话,我怎么不等待更多的数据呢?

1 个答案:

答案 0 :(得分:1)

我想我解决了它。没有方法可以询问是否有更多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())
{
    ...
}