PDA

View Full Version : make trewidget's xml file



Shien
1st January 2011, 16:43
I have tree widget. After clicking create button I want that there would be created xml file, which has tree widget's data. Is it possible to do that? If so maybe somebody could tell me how to do that?

Added after 1 8 minutes:

I found some examples in few books. but when I trie to use them few errors

there goes examples:

bool writeXml(const QString &fileName, QTreeWidget *treeWidget)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
std::cerr << "Error: Cannot write file "
<< qPrintable(fileName) << ": "
<< qPrintable(file.errorString()) << std::endl;
return false;
}
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("bookindex");
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
writeIndexEntry(&xmlWriter, treeWidget->topLevelItem(i));
xmlWriter.writeEndDocument();
file.close();
if (file.error()) {
std::cerr << "Error: Cannot write file "
<< qPrintable(fileName) << ": "
<< qPrintable(file.errorString()) << std::endl;
return false;
}
return true;
}


void writeIndexEntry(QXmlStreamWriter *xmlWriter, QTreeWidgetItem *item)
{
xmlWriter->writeStartElement("entry");
xmlWriter->writeAttribute("term", item->text(0));
QString pageString = item->text(1);
if (!pageString.isEmpty()) {
QStringList pages = pageString.split(", ");
foreach (QString page, pages)
xmlWriter->writeTextElement("page", page);
}
for (int i = 0; i < item->childCount(); ++i)
writeIndexEntry(xmlWriter, item->child(i));
xmlWriter->writeEndElement();
}

So errors that ocurred is with std::cerr and another error that QFile file(fileName); file name wasn't described.

By the way in this example if I do understand it correctly there should be created file before tree is placed there?

tbscope
1st January 2011, 17:31
To use std::cerr, include the iostream header. Or, alternatively, use qDebug.

As for the file being created:
To quote the documentation:

Note: In WriteOnly or ReadWrite mode, if the relevant file does not already exist, this function will try to create a new file before opening it.

Can you post the exact errors? This way it is easier to give specific help.

Note too that the saving of the tree in the example above is very specific to a certain structure.
You should use some sort of general recursive function.

Shien
1st January 2011, 23:57
I found one more example

#include <QtGui>

#include "xbelwriter.h"

XbelWriter::XbelWriter(QTreeWidget *treeWidget)
: treeWidget(treeWidget)
{
xml.setAutoFormatting(true);
}

bool XbelWriter::writeFile(QIODevice *device)
{
xml.setDevice(device);

xml.writeStartDocument();
xml.writeDTD("<!DOCTYPE xbel>");
xml.writeStartElement("xbel");
xml.writeAttribute("version", "1.0");
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
writeItem(treeWidget->topLevelItem(i));

xml.writeEndDocument();
return true;
}

void XbelWriter::writeItem(QTreeWidgetItem *item)
{
QString tagName = item->data(0, Qt::UserRole).toString();
if (tagName == "folder") {
bool folded = !treeWidget->isItemExpanded(item);
xml.writeStartElement(tagName);
xml.writeAttribute("folded", folded ? "yes" : "no");
xml.writeTextElement("title", item->text(0));
for (int i = 0; i < item->childCount(); ++i)
writeItem(item->child(i));
xml.writeEndElement();
} else if (tagName == "bookmark") {
xml.writeStartElement(tagName);
if (!item->text(1).isEmpty())
xml.writeAttribute("href", item->text(1));
xml.writeTextElement("title", item->text(0));
xml.writeEndElement();
} else if (tagName == "separator") {
xml.writeEmptyElement(tagName);
}
}

but I don't understand it.

bool XbelWriter::writeFile(QIODevice *device)
{
xml.setDevice(device); does that means file name?

tbscope
2nd January 2011, 09:21
A QIODevice can mean any device that is able to read, write or both.
A serial port for example, a printer, a usb memory stick, a tcp socket. But in most general cases it is just a file.
A QFile is a QIODevice. So you can just pass your QFile object to the writeFile function.

I guess the creators of this function had other devices in mind besides a QFile, like a network connection.

Shien
2nd January 2011, 12:48
But this example is only for one column tree widget? I have 2 column tree widget.

tbscope
2nd January 2011, 13:26
The last example uses 2 columns.
See the text(0) and text(1) function calls in the example.

Shien
2nd January 2011, 20:49
I found something that i need but the problem is that I can't align as I want.

for (int i = 0; i < treeW->topLevelItemCount(); ++i)
{
xmlWriter.writeEmptyElement(treeW->topLevelItem(i)->text(0));
xmlWriter.writeTextElement("Type",treeW->topLevelItem(i)->text(1));
xmlWriter.writeTextElement("Resource",treeW->topLevelItem(i)->text(2));
}

this code would make :

<Dwelling: 1/>
<Type>Liquid</Type>
<Resource>item1</Resource>
<Dwelling: 2/>
<Type>Etherial</Type>
<Resource>item1</Resource>

But I need something like this:


<Dwelling: 1>
<Type>Liquid</Type>
<Resource>item1</Resource>
</Dwelling: 1>
<Dwelling: 2/>
<Type>Etherial</Type>
<Resource>item1</Resource>
</Dwelling: 2>


how to make this?

tbscope
2nd January 2011, 20:54
I guess you need a start and end element.
See the documentation

Shien
2nd January 2011, 20:58
but I already have one
those elements are inside of it.

tbscope
2nd January 2011, 20:59
Then you don't use them correctly I guess.

Shien
2nd January 2011, 21:01
no I needed writeStartElement. Thanks

d_stranz
3rd January 2011, 00:07
I do not think that <Dwelling: 1> and so forth is correct XML syntax. If you are trying to enumerate things, then this syntax would be correct:

<Dwelling unit="1">
</Dwelling>

In other words, you can't put arbitrary text into elements. "Dwelling:" is not an acceptable element name, and the numeral "1" all by itself has no meaning in XML.

Your elements must have the form: <ElementName attributeName="attributeValue> </ElementName>
or <ElementName attributeName="attrbuteValue" />

In the first case, you can have child elements between the <ElementName> and </ElementName> start and end tags. In the second case, the entire element is contained within the tag - you can't have child elements inside it.

A proper XML writer will enforce correct syntax. If you write out the XML by hand, then what you have written will not pass a syntax check by a real XML parser.