问题
I want to Save Configuration Settings to XML file in QT and read it from there ?
What is best approach to do this in QT ?
Any sample/ideas are highly appreciated.
Thanks.
回答1:
You can register your XML file format with QSettings::registerFormat
Here's a sample implementation of the readXmlFile and writeXmlFile
回答2:
There is Qt examples for XML.
Also you can use QSettings to store your settings.
回答3:
Here is my code for exporting settings to XML. What you need is to call ExportSettingsToXml()
with opened for writing QFile. The exported file can be imported again with ImportSettingsFromXml()
.
QString Variant2Text( const QVariant &value )
{
switch (value.type())
{
case QVariant::String:
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
case QVariant::Bool:
return value.toString();
}
QByteArray ba;
value.save(QDataStream(&ba, QIODevice::WriteOnly));
return QString(ba.toHex());
}
QVariant Text2Variant( const QString &sText, QVariant::Type nType )
{
switch (nType)
{
case QVariant::String:
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
case QVariant::Bool:
{
QVariant var(sText);
if (var.convert(nType))
return var;
return QVariant(sText);
}
return QVariant::fromValue(sText);
}
QVariant value;
value.load(QDataStream(&QByteArray::fromHex(sText.toLatin1()), QIODevice::ReadOnly));
return value;
}
void XmlExportSettingsRecursive(QXmlStreamWriter &writer, QSettings &settings, const QStringList &blackList)
{
QString sGroup = settings.group();
if (!sGroup.isEmpty())
{
writer.writeStartElement("group");
writer.writeAttribute(QStringLiteral("name"), sGroup.mid(sGroup.indexOf(QChar('/')) + 1));
}
// Write child groups first
{
const QStringList &listGroups = settings.childGroups();
foreach (const QString &group, listGroups)
{
settings.beginGroup(group);
XmlExportSettingsRecursive(writer, settings, blackList);
settings.endGroup();
}
}
const QStringList &listKeys = settings.childKeys();
foreach (const QString &key, listKeys)
{
if (blackList.contains(key))
continue;
writer.writeStartElement("key");
writer.writeAttribute(QStringLiteral("name"), key);
const QVariant &value = settings.value(key);
writer.writeAttribute(QStringLiteral("type"), value.typeName());
writer.writeCharacters(Variant2Text(value));
writer.writeEndElement();
}
if (!sGroup.isEmpty())
writer.writeEndElement();
}
bool XmlImportSettingsRecursive(QXmlStreamReader &reader, QSettings &settings)
{
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement())
{
if (reader.name() == QStringLiteral("group"))
{
const QXmlStreamAttributes &attr = reader.attributes();
QString sGroup = attr.value(QStringLiteral("name")).toString();
settings.beginGroup(sGroup);
if (!XmlImportSettingsRecursive(reader, settings))
return false;
settings.endGroup();
}
else if (reader.name() == QStringLiteral("key"))
{
const QXmlStreamAttributes &attr = reader.attributes();
const QString &sKey = attr.value(QStringLiteral("name")).toString();
const QString &sType = attr.value(QStringLiteral("type")).toString();
if (reader.readNext())
{
if (reader.isCharacters() || reader.isEndElement())
{
const QString &sValue = reader.text().toString();
settings.setValue(sKey, Text2Variant(sValue, QVariant::nameToType(sType.toLatin1())));
}
else
continue;
}
}
}
else if (reader.isEndElement() && reader.name() == QStringLiteral("group"))
return true;
}
if (reader.hasError()) {
qDebug()<<reader.errorString();
return false;
}
return true;
}
bool ExportSettingsToXml( QIODevice *device, const QString &settingsGroup = QString(), const QStringList &blackList = QStringList())
{
if (!device || !device->isWritable())
return false;
QSettings settings;
settings.beginGroup(settingsGroup);
QXmlStreamWriter xmlWriter( device );
xmlWriter.setAutoFormatting( true );
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement( QStringLiteral("settings") );
if (!settingsGroup.isEmpty())
{
xmlWriter.writeStartElement(QStringLiteral("group"));
xmlWriter.writeAttribute(QStringLiteral("name"), settingsGroup);
}
XmlExportSettingsRecursive(xmlWriter, settings, blackList);
if (!settingsGroup.isEmpty())
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
return true;
}
bool ImportSettingsFromXml( QIODevice *device, const QString &settingsGroup = QString())
{
if (!device || !device->isReadable())
{
qDebug()<<"Trying to import XML settings from non-readable device";
return false;
}
QSettings settings;
settings.beginGroup(settingsGroup);
QXmlStreamReader xmlReader( device );
xmlReader.readNext();
if (!xmlReader.isStartDocument())
{
qDebug()<<"Invalid xml document format";
return false;
}
if (!xmlReader.readNextStartElement())
{
qDebug()<<"Empty settings xml document";
return true;
}
if (xmlReader.name() == QStringLiteral("settings") )
{
if (!XmlImportSettingsRecursive(xmlReader, settings))
return false;
}
else
{
qDebug()<<"Unknown settings format.";
return false;
}
return true;
}
回答4:
For such things I often use the boost library for C+ and can highly recommend it. It offers serialization for various formats like XML, text, binary etc.
Serialization Tutorial (looks more complicated that it actually is)
来源:https://stackoverflow.com/questions/6593749/save-configuration-settings-to-xml-file-in-qt