C++ QXmlStreamReader:can';t遵循readNextStartElement()的流程

C++ QXmlStreamReader:can';t遵循readNextStartElement()的流程,c++,xml,qt,qxmlstreamreader,C++,Xml,Qt,Qxmlstreamreader,我必须实现一个xml解析器,在运行时在小部件中构造和放置Qt对象。我编写了一个基于。一个模块表示将保存QPushButton和QCheckBox实例的QWidgetxml是一个QXmlStreamReader,就像Qt参考中的示例一样 因此,这里我尝试解析这个非常基本的xml文件: <somexml version="1.0"> <module> <button label="Send UART" define="BUTTON0" pos="

我必须实现一个xml解析器,在运行时在小部件中构造和放置Qt对象。我编写了一个基于。一个模块表示将保存
QPushButton
QCheckBox
实例的
QWidget
xml
是一个
QXmlStreamReader
,就像Qt参考中的示例一样

因此,这里我尝试解析这个非常基本的xml文件:

<somexml version="1.0">
    <module>
        <button label="Send UART" define="BUTTON0" pos="30, 30" size="20, 10">
            <action cmd="sendCom" data="0xAA 0xBB 0xCC"/>
        </button>
        <checkbox label="Send UART" define="CHECKBOX0" pos="250, 30" size="20, 10">
            <action cmd="sendCom" data="test"/>
        </checkbox>
        <button label="Check BIT" define="BUTTON1" pos="140, 30" size="20, 10">
            <action cmd="setDef" data="BUTTON0=1"/>
        </button>   
    </module>
</somexml>
我希望读取module元素并输入
readModule
的范围,它会这样做。在
readModule
中,我真的很难遵循解析流程

以下是实施方案:

void XmlReader::readModule()
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "module");


    while (xml.readNextStartElement())
    {
        if (xml.name() == "button")
        {
            readButton(widget);
        }
        else if (xml.name() == "checkbox")
        {
            readCheckBox(widget);
        }
        else
        {
            xml.skipCurrentElement();
        }
    }
}
它将只到达xml文件中的第一个
按钮
元素,并创建一个按钮。发送UART

当我将
readXml
的实现更改为:

void XmlReader::readXml()
{
    while (xml.readNextStartElement())
    {
        if (xml.name() == "module")
        {
            readModule();
        }
        else if (xml.name() == "button")
        {
            readButton(widget);
        }
        else if (xml.name() == "checkbox")
        {
            readCheckBox(widget);
        }
        else
        { 
            xml.skipCurrentElement();
        }
    }
}
它将到达第一个按钮和第一个复选框。我错过了什么

编辑:添加了readButton的实现

void XmlReader::readButton(Widget *widget)
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "button");

    QString label = xml.attributes().value("label").toString();
    QString define = xml.attributes().value("define").toString();

    QString pos = xml.attributes().value("pos").toString();
    QStringList posList = pos.split(",");
    int posX = posList[0].toInt();
    int posY = posList[1].toInt();

    QString size = xml.attributes().value("size").toString();
    QStringList sizeList= size.split(",");
    int sizeX = sizeList[0].toInt();
    int sizeY = sizeList[1].toInt();

    QString cmd, data;

    while (xml.readNextStartElement())
    {
        if (xml.name() == "action") 
        {
            cmd = xml.attributes().value("cmd").toString();
            data = xml.attributes().value("data").toString();
        }
        else
        {
            xml.skipCurrentElement();
        }
    }

    if (cmd == "sendCom")
    {
        widget->createButton(label, define, posX, posY,
                SLOT(sendCom(QString)), data);
    }
    else if (cmd == "setDef")
    {
        widget->createButton(label, define, posX, posY,
                SLOT(setDef(QString)), data);
    }
}

您需要使用
xml.skipCurrentElement()在<代码>读取按钮(小部件)之后
readCheckBox(小部件)。如果没有这个
xml,readNextStartElement()
将读取元素的结尾并中断循环

void XmlReader::readModule()
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "module");

    while (xml.readNextStartElement())
    {
        if (xml.name() == "button")
        {
            readButton(widget);
            xml.skipCurrentElement();
        }
        else if (xml.name() == "checkbox")
        {
            readCheckBox(widget);
            xml.skipCurrentElement();
        }
        else
        {
            xml.skipCurrentElement();
        }
    }
}

如何实现
readButton(小部件)?可能在readButton
xml之后。readNextStartElement()
返回值下降,因为它读取“end element”(例如),循环中断。添加了实现尝试添加
xml.readElementText()读取后按钮和读取后复选框。或
xml.skipCurrentElement()我认为两者都会有帮助。这是可行的,但术语
skipcurrentement
对我来说仍然相当不直观。
void XmlReader::readModule()
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "module");

    while (xml.readNextStartElement())
    {
        if (xml.name() == "button")
        {
            readButton(widget);
            xml.skipCurrentElement();
        }
        else if (xml.name() == "checkbox")
        {
            readCheckBox(widget);
            xml.skipCurrentElement();
        }
        else
        {
            xml.skipCurrentElement();
        }
    }
}