QXmlStreamReader: не может следить за потоком readNextStartElement ()

Я должен реализовать синтаксический анализатор xml, который создает и помещает объекты Qt в виджет во время выполнения. Я написал парсер на основе этот. Модуль представляет QWidget что будет держать QPushButton а также QCheckBox экземпляров. 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>

Модуль Element создаст виджет для хранения флажков и кнопок внутри тегов. Так вот:

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();
}
}
}

Дойдет только до первого button элемент в файле 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);
}
}

1

Решение

Вам нужно использовать xml.skipCurrentElement(); после readButton(widget); а также readCheckBox(widget);, Без этого 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();
}
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]