IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Discussion :

QXmlStreamReader

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Par défaut QXmlStreamReader
    Bonjour à tous, voila j'ai un soucis avec QXmlStreamReader.
    Enfin pas vraiment un soucis mais je n'arrive pas à faire ce que je veux.
    A partir de mon fichier .ui obtenu avec QtDesigner (une simple interface données patients), je souhaiterais pouvoir créer un fichier xml qui contient uniquement le nom des champs à remplir dans le formulaire.
    Voici un bref extrait du fichier pour vous donner une idée :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
        <item row="1" column="1">
         <widget class="QTextEdit" name="ContexteExamen_2">
          <property name="font">
           <font>
            <pointsize>10</pointsize>
           </font>
          </property>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QLabel" name="TypeExamen">
          <property name="palette">
           <palette>
            <active>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>255</red>
                <green>0</green>
                <blue>0</blue>
               </color>
              </brush>
             </colorrole>
            </active>
            <inactive>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>255</red>
                <green>0</green>
                <blue>0</blue>
               </color>
              </brush>
             </colorrole>
            </inactive>
            <disabled>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>28</red>
                <green>57</green>
                <blue>86</blue>
               </color>
              </brush>
             </colorrole>
            </disabled>
           </palette>
          </property>
          <property name="font">
           <font>
            <pointsize>10</pointsize>
           </font>
          </property>
          <property name="text">
           <string>Type d'EEG (*)</string>
          </property>
         </widget>
        </item>

    En gros ce que je souhaiterais faire, c'est prendre uniquement les widgets qui ont pour attribut class "QLabel", et ensuite extraire de ces widget la valeur de leur "string", dans mon exemple seul le 2eme widget m'interesse puisqu'il est de type QLabel, et son string serait "Type d'EEG".

    J'arrive à détecter chaque widget, et à déterminer si son attribut class est "QLabel" ou non avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    void mafenetre::lectureFormulaire()
    {
        QXmlStreamReader reader;
        QString filename="mafenetre.ui";
        QFile file(filename);
        file.open(QFile::ReadOnly | QFile::Text);
        reader.setDevice(&file);
     
        reader.readNext();
     
        while(!reader.atEnd()){
     
            reader.readNext();
     
            if(reader.isStartElement()){
     
               if(reader.name() == "widget"){
     
                   QXmlStreamAttributes attrs = reader.attributes();
                   QString tmp = attrs.value("class").toString();
     
                   if(tmp == "QLabel"){
     
                            /* ici le code à compléter ... */
     
                            }
     
                        }
     
                   }
     
                }
     
            }
     
        }
     
        file.close();
     
    }
    Ma question est donc la suivante, une fois que j'ai bien detecté que mon widget est un QLabel, comment faire pour extraire son string? Comment indiquer au reader qu'il doit extraire UNIQUEMENT les strings dont les widget sont des QLabel?

    Merci d'avance. Si ma question n'est pas claire (et je peux le concevoir) n'hésitez pas à me demander des précisions

  2. #2
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Hello,

    Personnellement je ferais quelque chose comme ça, par contre je n'arrive pas à obtenir le texte avec la fonction ReadElementText() depuis le QXmlStreamReader, je n'ai pas trouvé de solution à ce problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    bool isQLabel = false;
            QString labelText;
     
            while(!reader.atEnd()){
                reader.readNext();
                if(reader.isStartElement()){
                    ui->textEdit->append(reader.name().toString());
                    //ui->textEdit->append(reader.readElementText());
     
                    if(reader.name().toString() == "widget"){
                        if(reader.attributes().value("class").toString() == "QLabel"){
                            isQLabel = true;
                        } else {
                            isQLabel = false;
                        }
                    }
     
                    if(reader.name() == "string" && isQLabel){
                        //On entrera dans cette condition que si nous sommes dans la proprieté "string" 
                        //d'un "widget" de "class" "QLabel", par contre readElementText() renvoi une chaîne vide.
                        labelText == reader.readElementText(); 
                        ui->textEdit->append("<b>Label Text is :" + labelText + "</b>");
                    }
                }
            }
    Par contre ne serais-ce pas plus simple d'utiliser les classe QDomDocument, QDomElement, etc... Les désavantage est qu'il faut connaître la structure du document à l'avance, mais ce n'est pas un problème dans ce cas.

    Voici un solution qui fonctionne avec les classes QDomXxx:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
        QDomDocument doc2("mydocument");
        QFile file("mafenetre.ui");
        file.open(QIODevice::ReadOnly);
        doc2.setContent(&file);
        file.close();    
     
     
        // print out the element names of all elements that are direct children
        // of the outermost element.
        QDomElement docElem = doc2.documentElement();
     
        QDomNode n = docElem.firstChild();
        while(!n.isNull()) {
            QDomElement e = n.toElement(); // try to convert the node to an element.
            if(!e.isNull()) {                
                qDebug() << qPrintable(e.tagName()) << endl; // the node really is an element.
                QDomElement e2 = e.firstChild().toElement();
                if(!e2.isNull()){
                    qDebug() << "   " << qPrintable(e2.tagName()) << endl; // the node really is an element.
                    QString cl = e2.attribute("class", "");
                    if(cl == "QLabel"){
                        qDebug() << "This is a QLabel";
     
                        //Search "text" property
                        QDomElement e3 = e2.firstChild().toElement();
                        while(!e3.isNull()){
                            qDebug() << "   " << qPrintable(e2.tagName()) << endl; // the node really is an element.
                            qDebug() << "   " << e3.attribute("name", "");
                            if(e3.tagName() == "property" && e3.attribute("name", "") == "text"){
                                QString text = e3.firstChild().toElement().text();
                                qDebug() << "Test of QLabel is : " << text;
                            }
                            e3 = e3.nextSibling().toElement();
                        }
                    }
                }
            }
            n = n.nextSibling();
        }
    Avec ce Xml (version posté à laquelle j'ai rajouter l'élément root "<ui>" et j'ai supprimer le contenu de "<palette>" pour simplifier) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
        <item row="1" column="1">
         <widget class="QTextEdit" name="ContexteExamen_2">
          <property name="font">
           <font>
            <pointsize>10</pointsize>
           </font>
          </property>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QLabel" name="TypeExamen">
          <property name="palette">
           <palette>        
           </palette>
          </property>
          <property name="font">
           <font>
            <pointsize>10</pointsize>
           </font>
          </property>
          <property name="text">
           <string>Type d'EEG (*)</string>
          </property>
         </widget>
        </item>
    </ui>
    J'éspère que ma réponse est claire. et désolé de ne pas avoir trouver de solution pour la lecture du texte avec la méthode utilisant le QXmlStreamReader.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Par défaut
    Bonjour, tout d'abord merci de votre réponse.
    Pas de soucis pour le QXmlStreamReader, je me suis retourné la tête dans tous les sens et je crois que ce n'est simplement pas possible de faire ça avec.
    Par contre, j'ai essayé avec l'API QDom juste après du coup, et je dois dire que je n'ai pas réussi non plus.

    Votre solution n'est malheureusement pas bonne non plus, je vais vous joindre le fichier .ui complet de mon projet pour que vous vous fassiez une meilleur idée de ce que je souhaite vraiment, mais en gros les éléments que je veux détecter dans le fichier ne sont pas forcément toujours de même hiérarchie, avec votre code, je n'analyse que les éléments de 3ème rang maximum (par rang j'entends indentation).
    Ce qui est logique puisque vous allez jusqu'à e3, ma question est donc la suivante : est-il possible de parcourir mon fichier xml, mais de ne retirer les <strings> QUE des widget dans l'attribut "class" est de valeur "QLabel" tout en sachant que ces éléments peuvent être de hiérarchie différente?

    Cela voudrait dire que je devrais utiliser un code similaire au votre, mais qui va par exemple jusqu'à e10 si mon widget d'attribut "QLabel" le plus lointain est donc au rang 10?

    PS : j'ai été obligé de convertir le fichier en .txt car je ne peux apparement pas joindre de fichier .ui ici.
    Aussi, j'ai enlevé la partie connections à la fin de celui-ci puisqu'il n'y aura pas de "QLabel" dans celle-ci.

    Merci.

    PS2 : en compilant votre code avec le fichier que je vous joins on obtient comme résultat :

    class

    widget

    property

    resources
    Fichiers attachés Fichiers attachés

  4. #4
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Citation Envoyé par misr123 Voir le message
    Ce qui est logique puisque vous allez jusqu'à e3, ma question est donc la suivante : est-il possible de parcourir mon fichier xml, mais de ne retirer les <strings> QUE des widget dans l'attribut "class" est de valeur "QLabel" tout en sachant que ces éléments peuvent être de hiérarchie différente?

    Cela voudrait dire que je devrais utiliser un code similaire au votre, mais qui va par exemple jusqu'à e10 si mon widget d'attribut "QLabel" le plus lointain est donc au rang 10?
    Comme je l'ai dit le désavantage avec cette méthode est qu'il faut connaître la structure du document à l'avance. Mais il est tout-à-fait possible de parcourir toute la hiérarchie du fichier xml sans connaître la structure à l'avance. En utilisant la récursivité par exemple. Mon exemple était la simplement pour montrer comment fonctionne QDomDocument mais il peut être largement amélioré pour être plus générique.

    Je n'ai malheureusemnt pas le temps de proposer un petit exemple pour l'instant. j'essayerai de le faire cet après-midi.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Par défaut
    Merci de votre réponse rapide, effectivement j'avais pensé à la récursivité mais je ne m'en sors vraiment pas, je vais faire autre chose en attendant.

    En relisant mon code j'avais à peu prés codé la même chose que vous, je suis débutant avec Qt et j'avoue que j'ai un petit peu de mal à imaginer une solution de récursivité dans ce cas.

  6. #6
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut Récursivité
    Hello,

    Voici un exemple utilisant la récursivité:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #include <QCoreApplication>
    #include <QDomDocument>
    #include <QFile>
    #include <QStringList>
    #include <QTextStream>
    #include <QDebug>
    #include <iostream>
     
    void browse(QDomNode n, QStringList &labelTexts)
    {
        while(!n.isNull()) {
     
            QDomElement e = n.toElement(); // try to convert the node to an element.
     
            if(e.attribute("class", "") == "QLabel"){
                qDebug() << "This is a QLabel";
     
                //Search "text" property inside QLabel
                QDomElement eTextProperty = e.firstChild().toElement();
                while(!eTextProperty.isNull()){
                    qDebug() << "   " << qPrintable(eTextProperty.tagName()) << endl; // the node really is an element.
                    qDebug() << "   " << eTextProperty.attribute("name", "");
                    if(eTextProperty.tagName() == "property" && eTextProperty.attribute("name", "") == "text"){
                        QString text = eTextProperty.firstChild().toElement().text();
                        labelTexts.append(text);
                        qDebug() << "Test of QLabel is : " << text;
                    }
                    eTextProperty = eTextProperty.nextSibling().toElement();
                }
     
            }
     
            if(n.hasChildNodes()){
                browse(n.firstChild(), labelTexts);
            }
     
            n = n.nextSibling();
        }
    }
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        bool ok = true;
        QDomDocument doc("mydocument");
        QFile file("xmlResponse.xml");
        if (!file.open(QIODevice::ReadOnly)){
            ok = false;
        } else {
            if (!doc.setContent(&file)) {
                file.close();
                ok = false;
            }
            file.close();
        }
     
        if(!ok) qDebug() << "\nerror\n";
     
        if(ok){
            // print out the element names of all elements that are direct children
            // of the outermost element.
            QDomElement docElem = doc.documentElement();
     
            QDomNode n = docElem.firstChild();
            QStringList labelTexts;
            browse(n, labelTexts);
     
            qDebug() << "Labels texts found: ";
            foreach(const QString &s , labelTexts){
                qDebug() << s;
            }
     
        }
     
        return a.exec();
    }
    J'obtiens le résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    "Conditions d'examen"
    "Question posΘe"
    "Informations sur l'examen"
    "Contexte de l'examen"
    "Type d'EEG (*)"
    "Traitement en cours"
    "DonnΘes imageries (si pertinentes)"
    "Debut de la symptomatologie"
    "RΘanimation (*)"
    "TempΘrature Corporelle"
    "SΘdation"
    "Arret cardio-respiratoire"
    "DurΘe du low-flow"
    "DurΘe du no-flow"
    "Informations sur le patient"
    "Nom (*)"
    "PrΘnom (*)"
    "DDN (*)"
    "NIP (*)"
    "Pb sous X"
    "Consetement ΘclairΘ"
    "Nom (*)"
    "TΘlΘphone (*)"
    "Lieu d'exercice (*)"
    "PrΘnom (*)"
    "Fax"
    "Informations sur le mΘdecin prescripteur"
    "Email"
    "Nom (*)"
    "TΘlΘphone (*)"
    "Lieu d'exercice (*)"
    "PrΘnom (*)"
    "Fax"
    "Email"
    "Informations sur le technicien"
    "Nom de la machine d'acquisition"
    "Email"
    "Adresse 1"
    "TΘlΘphone"
    "Ville"
    "Service"
    "Adresse 2"
    "Nom"
    "Code Postal"
    "Informations sur l'hopital "
    "Les champs suivis d'une (*) sont obligatoires"
    Par contre il semble y avoir un petit problème au niveau de l'encodage des caractères. En effets les "é" ne sont pas reconnus correctement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QtCore] Lecture d'un fichier xml avec QXmlStreamReader
    Par Jiyuu dans le forum PyQt
    Réponses: 0
    Dernier message: 11/04/2014, 13h48
  2. Questions sur QXmlStreamReader et sur les Regexp
    Par jderam dans le forum Débuter
    Réponses: 2
    Dernier message: 06/05/2009, 12h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo