QSettings and xml
-
I'm trying to work with QSettings and xml file. This is my attempt
file.h
@
#include <QSettings>#ifndef QCONTROLPANEL_H
#define QCONTROLPANEL_Hclass QControlPanel : public QDialog
{
Q_OBJECTpublic:
explicit QControlPanel(QWidget *parent = 0);~QControlPanel();
public slots:
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);private:
QSettings *settings;private slots:
signals:
};
#endif // QCONTROLPANEL_H
@file .cpp
@
// —› QControlPanel methods ‹—#include "QControlPanel.h"
QControlPanel::QControlPanel(QWidget *parent) :
QDialog(parent)
{
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);QSettings::Format XmlFormat = QSettings::registerFormat("xml", readXmlFile, writeXmlFile); settings = new QSettings(XmlFormat, QSettings::UserScope, "Organisation", "Name");
}
QControlPanel::~ QControlPanel()
{
}bool QControlPanel::readXmlFile(QIODevice &device, QSettings::SettingsMap &map) {
QXmlStreamReader xmlReader(&device);
QStringList elements;// Solange Ende nicht erreicht und kein Fehler aufgetreten ist
while (!xmlReader.atEnd() && !xmlReader.hasError()) {
// Nächsten Token lesen
xmlReader.readNext();// Wenn Token ein Startelement if (xmlReader.isStartElement() && xmlReader.name() != "Settings") { // Element zur Liste hinzufügen elements.append(xmlReader.name().toString()); // Wenn Token ein Endelement } else if (xmlReader.isEndElement()) { // Letztes Element löschen if(!elements.isEmpty()) elements.removeLast(); // Wenn Token einen Wert enthält } else if (xmlReader.isCharacters() && !xmlReader.isWhitespace()) { QString key; // Elemente zu String hinzufügen for(int i = 0; i < elements.size(); i++) { if(i != 0) key += "/"; key += elements.at(i); } // Wert in Map eintragen map[key] = xmlReader.text().toString(); }
}
// Bei Fehler Warnung ausgeben
if (xmlReader.hasError()) {
qWarning() << xmlReader.errorString();
return false;
}return true;
}bool QControlPanel::writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map) {
QXmlStreamWriter xmlWriter(&device);xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("Settings");QStringList prev_elements;
QSettings::SettingsMap::ConstIterator map_i;// Alle Elemente der Map durchlaufen
for (map_i = map.begin(); map_i != map.end(); map_i++) {QStringList elements = map_i.key().split("/"); int x = 0; // Zu schließende Elemente ermitteln while(x < prev_elements.size() && elements.at(x) == prev_elements.at(x)) { x++; } // Elemente schließen for(int i = prev_elements.size() - 1; i >= x; i--) { xmlWriter.writeEndElement(); } // Elemente öffnen for (int i = x; i < elements.size(); i++) { xmlWriter.writeStartElement(elements.at(i)); } // Wert eintragen xmlWriter.writeCharacters(map_i.value().toString()); prev_elements = elements;
}
// Noch offene Elemente schließen
for(int i = 0; i < prev_elements.size(); i++) {
xmlWriter.writeEndElement();
}xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();return true;
}
@But after debug, Qt Creator tells me these error messages:
C:\Users\Marco\untitled4\QControlPanel.cpp:120: error: undefined reference to
writeXmlFile(QIODevice&, QMap<QString, QVariant> const&)' C:\Users\Marco\untitled4\QControlPanel.cpp:120: error: undefined reference to
readXmlFile(QIODevice&, QMap<QString, QVariant>&)'
collect2.exe:-1: error: error: ld returned 1 exit statusCould you help me? I have drawn inspiration from this example: http://www.openshots.de/2011/03/qsettings-mit-xml-format/
-
I don't see any issue here. Can you just do clean and do the build again ?
-
According to "QSettings::registerFormat":http://qt-project.org/doc/qt-5/qsettings.html#registerFormat documentation the writeFunc and readFunc must be either standalone function or static member functions.
In the "example that you used":http://www.openshots.de/2011/03/qsettings-mit-xml-format/ both functions are standalone functions.Move both functions out of the class or make them the static functions of the class.
-
Why do you declare writeXmlFile and readXmlFile again in the lines 8 and 9 in file.cpp above?
Hi Andreyc, I have been finding "Qsettings-mit-xml-format", but the link http://www.openshots.de/2011/03/qsettings-mit-xml-format/ is broken, is there some way for i can see this example? thanks
-
Hi Andreyc, I have been finding "Qsettings-mit-xml-format", but the link http://www.openshots.de/2011/03/qsettings-mit-xml-format/ is broken, is there some way for i can see this example? thanks
@zabdielfer said in QSettings and xml:
Hi Andreyc, I have been searching "Qsettings-mit-xml-format", but the link http://www.openshots.de/2011/03/qsettings-mit-xml-format/ is broken, is there some way for i can see this example? thanks
-
@zabdielfer as @andreyc sayed. You have to change the methods readXmlFile and writeXmlFile to static members..
Especially:
in your header file:
changebool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);to
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);and remove in the implementation file (QControlPanel constructor) the forward declarations
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map); -
@zabdielfer as @andreyc sayed. You have to change the methods readXmlFile and writeXmlFile to static members..
Especially:
in your header file:
changebool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);to
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);and remove in the implementation file (QControlPanel constructor) the forward declarations
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);@karlheinzreichel
thank you, I will try it -
@karlheinzreichel
thank you, I will try itThis post is deleted! -
@zabdielfer as @andreyc sayed. You have to change the methods readXmlFile and writeXmlFile to static members..
Especially:
in your header file:
changebool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);to
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);and remove in the implementation file (QControlPanel constructor) the forward declarations
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);@zabdielfer
Hi:
how could I get all attributes of a node for example this xml file
<Ajustes>
<Personalizado>
<AjustesECG setting_ecg.V_on="false" setting_ecg.marcapasos="false" setting_ecg.alarm_on_st2="true" />
<AjustesRSP setting_rsp.gain="2" setting_rsp.apnea_delay="1" setting_rsp.alarm_on="true" />
<AjustesNIBP setting_pni.period="2" setting_pni.alarm_sy_on="true" setting_pni.alarm_di_on="true"
<AjustesCO2 setting_cos.apnea_delay="1" setting_cos.compensation="false" setting_cos.alarm_cex_on="true" />
<AjustesNO2 setting_nos.alarm_nex_on="false" setting_nos.alarm_nin_on="false" setting_nos.alarm_nex_lvl="1"
<AjustesTNM setting_nmt.current="0" setting_nmt.period="0" setting_nmt.type="0" setting_nmt.width="0" />
</Personalizado>
<Fabrica>
<AjustesECG setting_ecg.V_on="false" setting_ecg.marcapasos="false" setting_ecg.alarm_on_st2="true" />
<AjustesRSP setting_rsp.gain="2" setting_rsp.apnea_delay="1" setting_rsp.alarm_on="true" />
<AjustesNIBP setting_pni.period="2" setting_pni.alarm_sy_on="true" setting_pni.alarm_di_on="true"
<AjustesCO2 setting_cos.apnea_delay="1" setting_cos.compensation="false" setting_cos.alarm_cex_on="true" />
<AjustesNO2 setting_nos.alarm_nex_on="false" setting_nos.alarm_nin_on="false" setting_nos.alarm_nex_lvl="1"
<AjustesTNM setting_nmt.current="0" setting_nmt.period="0" setting_nmt.type="0" setting_nmt.width="0" />
</Fabrica>
</Ajustes> -
@zabdielfer
Hi:
how could I get all attributes of a node for example this xml file
<Ajustes>
<Personalizado>
<AjustesECG setting_ecg.V_on="false" setting_ecg.marcapasos="false" setting_ecg.alarm_on_st2="true" />
<AjustesRSP setting_rsp.gain="2" setting_rsp.apnea_delay="1" setting_rsp.alarm_on="true" />
<AjustesNIBP setting_pni.period="2" setting_pni.alarm_sy_on="true" setting_pni.alarm_di_on="true"
<AjustesCO2 setting_cos.apnea_delay="1" setting_cos.compensation="false" setting_cos.alarm_cex_on="true" />
<AjustesNO2 setting_nos.alarm_nex_on="false" setting_nos.alarm_nin_on="false" setting_nos.alarm_nex_lvl="1"
<AjustesTNM setting_nmt.current="0" setting_nmt.period="0" setting_nmt.type="0" setting_nmt.width="0" />
</Personalizado>
<Fabrica>
<AjustesECG setting_ecg.V_on="false" setting_ecg.marcapasos="false" setting_ecg.alarm_on_st2="true" />
<AjustesRSP setting_rsp.gain="2" setting_rsp.apnea_delay="1" setting_rsp.alarm_on="true" />
<AjustesNIBP setting_pni.period="2" setting_pni.alarm_sy_on="true" setting_pni.alarm_di_on="true"
<AjustesCO2 setting_cos.apnea_delay="1" setting_cos.compensation="false" setting_cos.alarm_cex_on="true" />
<AjustesNO2 setting_nos.alarm_nex_on="false" setting_nos.alarm_nin_on="false" setting_nos.alarm_nex_lvl="1"
<AjustesTNM setting_nmt.current="0" setting_nmt.period="0" setting_nmt.type="0" setting_nmt.width="0" />
</Fabrica>
</Ajustes>@zabdielfer
QXmlStreamReader * rdr = new QXmlStreamReader("path");while (!rdr->atEnd()) { QXmlStreamReader::TokenType token = rdr->readNext(); if(token == QXmlStreamReader::StartDocument) continue; if (rdr->name() == "Personalizado") { continue; } if(rdr->name() == "AjustesECG"){ qDebug() << rdr->attributes().value("setting_ecg.V_on").toString(); qDebug() << rdr->attributes().value("setting_ecg.marcapasos").toString(); qDebug() << rdr->attributes().value("setting_ecg.alarm_on_st2").toString(); } }
-
@zabdielfer
QXmlStreamReader * rdr = new QXmlStreamReader("path");while (!rdr->atEnd()) { QXmlStreamReader::TokenType token = rdr->readNext(); if(token == QXmlStreamReader::StartDocument) continue; if (rdr->name() == "Personalizado") { continue; } if(rdr->name() == "AjustesECG"){ qDebug() << rdr->attributes().value("setting_ecg.V_on").toString(); qDebug() << rdr->attributes().value("setting_ecg.marcapasos").toString(); qDebug() << rdr->attributes().value("setting_ecg.alarm_on_st2").toString(); } }
@Taz742
Thank you for spent time in my topic. :) -
@Taz742
Thank you for spent time in my topic. :)@zabdielfer
Is it helpfull for you? -
@zabdielfer
Is it helpfull for you?@Taz742
yes, thank you