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

Qt Discussion :

[Qt4] Trier un QtreeWidget en fonction d'un entier


Sujet :

Qt

  1. #1
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut [Qt4] Trier un QtreeWidget en fonction d'un entier
    Salut,

    J'utilise actuellement un élément TreeWidget pour créer un arbre. Dans cette arbre, j'ai une colonne contenant un entier. Jusque là tout va bien, mais lorsque je lui demande de me trier mes entiers il le fait par ordre alphabétique et non de grandeur.

    Y aurait-il une fonction qui permettrait de lui dire que c'est par ordre entier et non alpha ?

  2. #2
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut
    J'ai vu quelque part qu'il faut redéfinir l'opérateur < mais l'exemple donné en fonctionne pas.

    Personne aurait un exemple sous la main et sans modèle

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Voici une solution.
    Demande ce que tu ne comprend pas

    Code C++ : 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 <QtGui>
     
    class MyQTreeWidgetItem :public QTreeWidgetItem
    {
        public :
            MyQTreeWidgetItem ( QTreeWidgetItem * parent, int type = Type ):QTreeWidgetItem(parent,type){};
            MyQTreeWidgetItem ( QTreeWidget * parent, int type = Type ):QTreeWidgetItem(parent,type){};
     
        //reimplemente le teste
        bool operator< ( const QTreeWidgetItem & other ) const
            {
           //on recupere la colone utilisee pour le test
            const QTreeWidget * pTree =treeWidget ();
            int colonne   =pTree->sortColumn();
     
            //on recupere les donnees situé dans la colone
            QVariant  q1= data ( colonne , 0 );
            QVariant  q2= other.data ( colonne , 0 );
            //on verifie que les deux variants sont de même type
            if (q1.type() ==q2.type())
                {
                //si se sont des int
                if (q1.type()==QVariant::Int)     return q1.toInt()<q2.toInt();
                //si se sont des double
                if (q1.type()==QVariant::Double)     return q1.toDouble()<q2.toDouble();
                }
            //Sinon on appèle le comparateur de la class QTreeWidgetItem
            return QTreeWidgetItem::operator<(other);
            }
     
    };
     
     
    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
     
        QTreeWidget tree;
     
        QStringList entete;
        entete << "valeur 1" << "valeur 2" ;
     
        tree.setHeaderItem(new QTreeWidgetItem((QTreeWidgetItem*)0,entete));
        tree.setSortingEnabled(true);
        srand(time(NULL));
        //on cree une premiere branche avec
        // valeur 1 : int entre 0 et 20
        // valeur 2 : double aléatoire entre 0 et 20
        MyQTreeWidgetItem *parentitem = new MyQTreeWidgetItem(&tree);
        parentitem->setText(0,"premiere serie");
     
        for (int i=0;i<20;++i)
            {
            MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
            item ->setData (0, 0, QVariant(i));
            item ->setData (1, 0, QVariant(static_cast<double >(rand())/RAND_MAX*i));
            }
     
        //on cree une deusieme branche avec
        // valeur 1 : int entre 0 et 20
        // valeur 2 : double aleatoire entre 0 et 20
        parentitem = new MyQTreeWidgetItem(&tree);
        parentitem->setText(0,"deusieme serie");
        for (int i=0;i<20;++i)
            {
            MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
            item ->setData (1, 0, QVariant(i));
            item ->setData (0, 0, QVariant(static_cast<double >(rand())/RAND_MAX*i));
            }
        tree.resize(200, 800);
        tree.expandAll();
        tree.show();
     
     QObject::connect(&tree, SIGNAL(clicked()), &app, SLOT(quit()));
        return app.exec();
    }

  4. #4
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut
    Ben là j'ai un petit soucis. J'ai voulu l'intégrer à mon treeview et là il n'accepte pas la construction à partir de cette classe.

  5. #5
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut
    Mon soucis vient de ceci :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    QList<MyQTreeWidgetItem *> liste = this->findItems(item->text(0), Qt::MatchExactly, 0);
    Ceci me permet de retrouver un item de ma liste mais visiblement il n'accepte pas le MyQTreeWidgetItem.

    erreur: conversion from «QList<QTreeWidgetItem*>" to non-scalar type «QList<MyQTreeWidgetItem*>" requested
    Je vais essayer un cast pour voir

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Je n'ai pas fait tout les constructeur. Faut que tu les rajoute

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Ca utilise le polymorphisme.

    il faut faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QList<QTreeWidgetItem *> liste = this->findItems(item->text(0), Qt::MatchExactly, 0);

  8. #8
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut
    En fait j'ai fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    QList<QTreeWidgetItem *> liste = this->findItems(item->text(0), Qt::MatchExactly, 0);
     
            if(liste.size() > 0)
            {
                colorize((MyQTreeWidgetItem *)liste[0], Qt::green);
                this->scrollToItem(liste[0], QAbstractItemView::PositionAtCenter);
                liste[0]->setExpanded(true);
            }
    Et là fonctionne correctement. C'était juste un soucis de cast.

    Pour la définition des constructeurs, t'inquiètes pas.

    tu m'as beaucoup aidé aujourd'hui

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    La c'est pareil.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    colorize((QTreeWidgetItem *)liste[0], Qt::green);
    suffit

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    IL manque un blindage.
    remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const QTreeWidget * pTree =treeWidget ();
    int colonne   =pTree->sortColumn();
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const QTreeWidget * pTree =treeWidget ();
    int colonne   =pTree ? pTree->sortColumn() : 0;

  11. #11
    Inactif  
    Avatar de Kerod
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    11 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 11 672
    Points : 20 778
    Points
    20 778
    Par défaut
    Tu es un bon

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kerod Voir le message
    Tu es un bon
    En faite c'est aussi pour
    http://www.developpez.net/forums/sho...d.php?t=475210
    D'ailleurs si tu as d'autre idée ou problème??

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par yan Voir le message
    Voici une solution.
    Demande ce que tu ne comprend pas

    Code C++ : 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
    [...]
     
    int main(int argc, char* argv[])
    {
       [...]
        for (int i=0;i<20;++i)
            {
            MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
            item ->setData (0, 0, QVariant(i));
            item ->setData (1, 0, QVariant(static_cast<double >(rand())/RAND_MAX*i));
            }
     
        //on cree une deusieme branche avec
        // valeur 1 : int entre 0 et 20
        // valeur 2 : double aleatoire entre 0 et 20
        parentitem = new MyQTreeWidgetItem(&tree);
        parentitem->setText(0,"deusieme serie");
        for (int i=0;i<20;++i)
            {
            MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
            item ->setData (1, 0, QVariant(i));
            item ->setData (0, 0, QVariant(static_cast<double >(rand())/RAND_MAX*i));
            }
       [...]
    }
    Merci Yan !

    Juste quelques remarques :
    • Si on utilise "item->setText( num_colonne, strTexte);" (en plus de "item->setData("...), le tri ne fonctionne plus ?!
    • Là tu as utilisé "setData( num_colonne, Qt:: DisplayRole, val );", ça veut dire qu'on ne peut plus utiliser d'autres rôles (comme Qt::ToolTipRole, Qt::WhatsThisRole, etc.)


    Je propose une autre version (testée) de comparaison pour le tri des items, pour ceux que ça intéresserait :
    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
     
    bool operator< ( const QTreeWidgetItem & other ) const
    	{
    		//on recupere la colone utilisee pour le test
    		const QTreeWidget * pTree =treeWidget ();
    		int colonne = pTree->sortColumn();
     
    		//on recupere les données situé dans la colone
    		QString str1 = text( colonne );
    		QString str2 = other.text( colonne );
    		bool bEstNumerique1, bEstNumerique2;
    		const int ncBase = 10;
    		int nEntier1 = str1.toInt( &bEstNumerique1, ncBase );
    		if ( bEstNumerique1 ) {
    			int nEntier2 = str2.toInt( &bEstNumerique2, ncBase );
    			if ( bEstNumerique2 ) return nEntier1 > nEntier2;
    		}
    		int nDouble1 = str1.toDouble( &bEstNumerique1 );
    		if ( bEstNumerique1 ) {
    			int nDouble2 = str2.toDouble( &bEstNumerique2 );
    			if ( bEstNumerique2 ) return nDouble1 > nDouble2;
    		}
    		return !(QTreeWidgetItem::operator<(other));
    	}// operator<
    Avec cette fonction, il faut remplir l'arbre comme ceci (le "setData" est optionnel) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    item ->setText (0, "12" );
    item ->setData (0, Qt::ToolTipRole, "Vitesse du vent" );// en option
    Remarque :
    Dans cette fonction de comparason, je renvoie pour l'instant l'inverse de ce qui attendu car l'indicateur "^" ou "chapeau vers le bas" dans les têtes de colonne du composant ne présentait par l'ordre de classement voulu. Il y a peut-être d'autres solutions.

    Merci encore Yan, ton post m'a bien dépanné.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Oups, j'ai posté de grosses erreurs dans le message précédent, je me dépèche de corriger :
    Citation Envoyé par MarcNop Voir le message
    Juste quelques remarques :
    • Si on utilise "item->setText( num_colonne, strTexte);" (en plus de "item->setData("...), le tri ne fonctionne plus ?!
    Le tri ne fonctionne pas si on ne fait pas un setData(..., Qt:: DisplayRole... )

    Citation Envoyé par MarcNop Voir le message
    • Là tu as utilisé "setData( num_colonne, Qt:: DisplayRole, val );", ça veut dire qu'on ne peut plus utiliser d'autres rôles (comme Qt::ToolTipRole, Qt::WhatsThisRole, etc.)
    Et si ! On peut faire plusieurs setData sur le même item !

    Citation Envoyé par MarcNop Voir le message
    Je propose une autre version (testée) de comparaison pour le tri des items,
    Voilà, finalement cette version ne sert à rien, celle de la FAQ est très bien !

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

Discussions similaires

  1. trier une table en fonction d'une autre
    Par boss_gama dans le forum Langage SQL
    Réponses: 7
    Dernier message: 18/10/2009, 11h17
  2. [MySQL] Trier les résultats en fonction d'une colonne ordre
    Par eclipse012 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 05/01/2007, 13h59
  3. Réponses: 6
    Dernier message: 20/07/2006, 11h25
  4. trier un etat en fonction d'une zone calculée
    Par petitours dans le forum Access
    Réponses: 1
    Dernier message: 07/06/2006, 15h05
  5. Trier les enregistrements en fonction de la date
    Par mpereg dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 12/09/2004, 14h16

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