gpt4 book ai didi

c++ - QXmlStreamReader:无法跟随 readNextStartElement() 的流程

转载 作者:数据小太阳 更新时间:2023-10-29 02:34:15 25 4
gpt4 key购买 nike

我必须实现一个 xml 解析器,它在运行时构造 Qt 对象并将其放置在小部件中。我写了一个基于 this 的解析器.一个模块代表 QWidget,它将包含 QPushButtonQCheckBox 实例。 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>

模块元素将创建一个小部件以将复选框和按钮保存在标签中。所以在这里:

void XmlReader::readXml()
{
while (xml.readNextStartElement())
{
if (xml.name() == "module")
{
readModule();
}
}
}

我希望读取模块元素并进入 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 文件中的第一个 button 元素并创建一个按钮。发送串口。

当我将 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);
}
}

最佳答案

您需要在 readButton(widget);readCheckBox(widget); 之后使用 xml.skipCurrentElement();。没有那个 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();
}
}
}

关于c++ - QXmlStreamReader:无法跟随 readNextStartElement() 的流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35017654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com