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_H

    class QControlPanel : public QDialog
    {
    Q_OBJECT

    public:
    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 &lt; 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&#40;QIODevice&, QMap<QString, QVariant> const&&#41;' C:\Users\Marco\untitled4\QControlPanel.cpp:120: error: undefined reference toreadXmlFile(QIODevice&, QMap<QString, QVariant>&)'
    collect2.exe:-1: error: error: ld returned 1 exit status

    Could 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 ?



  • Why do you declare writeXmlFile and readXmlFile again in the lines 8 and 9 in file.cpp above?



  • 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.



  • @andreyc

    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:

    @andreyc

    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:
    change

    bool 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



  • This post is deleted!


  • @karlheinzreichel

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


  • @Taz742
    Thank you for spent time in my topic. :)



  • @zabdielfer
    Is it helpfull for you?



  • @Taz742
    yes, thank you


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.