IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Le contenu de Qt4 > QtGui > Model View
        Qu'est ce que Model View ?
        Comment trier un QTreeWidget ?
        Comment trier un QListWidget ?
        Comment effacer le contenu d'un QTableWidget ?



Qu'est ce que Model View ?
auteur : Benjamin Poulain
Model View est l'infrastructure de Qt qui permet de gérer les vues arborescentes, les listes et les tables. Il se base sur un pattern Modèle-View-Delegate.

Le modèle est une interface vers les données, ce qui permet d'abstraire la façon dont celle-ci sont représentées (mémoire, base de données, système de fichier, etc).

La vue est la représentation visuelles des données sur l'écran. Qt fourni trois types de représentations: liste (QListView), arbre (QTreeView) et tableaux (QTableView).

Le délégué permet de faire le lien entre la vue et le modèle. Le délégué se charge de dessiner les éléments du modèle dans la vue, et de gérer l'édition de ces éléments.

Par rapport à Modèle-Vue-Controleur, le délégué est une sorte de super contrôleur. Il génère un éditeur à la demande de la vue, et se charge de faire parvenir les informations au modèle, c'est son rôle de contrôleur. En plus de cela, le délégué se charge de dessiner les éléments du modèle, ce qui permet de pouvoir complètement personnaliser la vue.
Voici un exemple d'utilisation de Model View en utilisant le système de fichier comme modèle

#include <QApplication>
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>
 
int main(int argc, char **argv)
{
   QApplication app(argc, argv);
   
   QFileSystemModel model; // le modèle est ici le système de fichier
   model.setRootPath(QDir::rootPath());
 
   QTreeView treeView;
   treeView.setModel(&model);
   QListView listView;
   listView.setModel(&model);
   QTableView tableView;
   tableView.setModel(&model);
 
   // partageons la selection pour plus de cohérence
   QItemSelectionModel *selection = treeView.selectionModel();
   listView.setSelectionModel(selection);
   tableView.setSelectionModel(selection);
 
   // changeons la racine en fonction de la selection 
   // (car les tables et listes en sont pas fait pour naviguer, on pourra toujours naviguer avec l'arbre)
   QObject::connect(selection, SIGNAL(currentChanged(const QModelIndex, const QModelIndex)), &listView, SLOT(setRootIndex(const QModelIndex)));
   QObject::connect(selection, SIGNAL(currentChanged(const QModelIndex, const QModelIndex)), &tableView, SLOT(setRootIndex(const QModelIndex)));
 
   treeView.show();
   listView.show();
   tableView.show();
 
   return app.exec();
}

Comment trier un QTreeWidget ?
auteur : Yan Verdavaine
Les QTreeWidget trient leurs items grâce à l'opérateur < des QTreeWidgetItem. Par défaut, cet opérateur compare deux QString. Malheureusement, ceci ne correspond pas toujours à ce que l'on souhaite.

Pour y remédier, il suffit de créer sa propre classe d'item qui hérite de QTreeWidgetItem et qui redéfinit cet opérateur.

Tout fonctionnera grâce au polymorphisme !

Exemple : différence entre le tri lexical de QTreeWidgetItem et le tri numérique implémenté par notre classe item
Trier un QTreeWidget

#include <QtGui>
#include <cstdlib>  //srand, rand et RAND_MAX
#include <ctime>    //time

class MyQTreeWidgetItem :public QTreeWidgetItem
{
public :
    //Constructeur de MyQTreeWidgetItem.
    MyQTreeWidgetItem ( QTreeWidgetItem * parent, int type = Type ):QTreeWidgetItem(parent,type){};
    MyQTreeWidgetItem ( QTreeWidget * parent, int type = Type ):QTreeWidgetItem(parent,type){};
    
    //Reimplemente le test
    bool operator< ( const QTreeWidgetItem & other ) const
    {
        //On recupere la colonne utilisee pour le test
        const QTreeWidget * pTree =treeWidget ();
        //Si aucun TreeWidget n'est associe, on utilise la colonne 0
        int colonne   = pTree ? pTree->sortColumn() : 0;
        
        //On recupere les donnees sous forme de variant 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 appele le comparateur de la class mere "QTreeWidgetItem"
        return QTreeWidgetItem::operator<(other);
    }

};


int main(int argc, char* argv[])
{
    srand(time(NULL));
    QApplication app(argc, argv);
    
    QTreeWidget tree;
    //On remplit l'entete
    QStringList entete;
    entete << "int" << "double" ;
    tree.setHeaderItem(new QTreeWidgetItem((QTreeWidgetItem*)0,entete));
    tree.setSortingEnabled(true);
    
    //On cree une premiere branche avec des QTreeWidgetItem
    //Les items seront tries de manière lexicale
    QTreeWidgetItem *parentitem = new QTreeWidgetItem(&tree);
    parentitem->setText(0,"QTreeWidgetItem");
    for (int i=0;i<20;++i)
    {
        QTreeWidgetItem*item = new QTreeWidgetItem(parentitem);
        item ->setData (0, 0, QVariant(i));
        item ->setData (1, 0, QVariant(rand()/(1.+RAND_MAX)*i));
    }
    
    //On cree une deuxieme branche avec notre nouvelle classe
    //Les items seront tries de maniere numerique
    parentitem = new MyQTreeWidgetItem(&tree);
    parentitem->setText(0,"MyQTreeWidgetItem ");
    for (int i=0;i<20;++i)
    {
        MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
        item ->setData (0, 0, QVariant(i));
        item ->setData (1, 0, QVariant(rand()/(1.+RAND_MAX)*i));
    }
    
    tree.resize(400, 650);
    tree.expandAll();
    tree.show();
    return app.exec();
}

Comment trier un QListWidget ?
auteur : Yan Verdavaine
Les QListWidget trient leurs items avec l'opérateur < des QListWidgetItem. Par défaut, cet opérateur compare deux QString. Malheureusement, ceci ne correspond pas toujours à ce que l'on souhaite. Pour y remédier, il suffit de créer sa propre classe d'item qui hérite de QListWidgetItem et qui redéfinit cet opérateur. Tout fonctionnera simplement grâce au polymorphisme.

Exemple : différence entre le tri par ordre croissant numérique implémenté par notre classe item (vue de gauche) et le tri par ordre croissant lexical des QListWidgetItem (vue de droite)
Trier un QListWidget

#include <QtGui>

class MyQListWidgetItem :public QListWidgetItem
{
public :
    //Constructeur de MyQListWidgetItem.
    MyQListWidgetItem ( QListWidget * parent, int type = Type ):QListWidgetItem(parent,type){};

   //Reimplemente le teste
   bool operator< ( const QListWidgetItem & other ) const
       {
       //On recupere les donnees sous forme de variant
       QVariant  q1= data ( 0 );
       QVariant  q2= other.data (  0 );
       //On verifie que les deux variants sont de même type
       if (q1.type() ==q2.type())
        {
           //Si ce sont des int
           if (q1.type()==QVariant::Int)     return q1.toInt()<q2.toInt();
           //Si ce sont des double
           if (q1.type()==QVariant::Double)     return q1.toDouble()<q2.toDouble();
        }
       //Sinon on appelle le comparateur de la classe mere "QListWidgetItem"
       return QListWidgetItem::operator<(other);
       }

};


int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    //Viewer  de gauche
    QListWidget  * pList1 = new QListWidget;
    //On active le tri. Par defaut, le tri est par ordre croissant
    pList1->setSortingEnabled(true);
    //On utilise nos items. Le tri se fera par ordre numerique
     for (int i=0;i<20;++i)
    {
       QListWidgetItem*item = new MyQListWidgetItem(pList1);
       item ->setData ( 0, QVariant(i));
    }

    //Viewer  de droite
    QListWidget  * pList2 = new QListWidget;
    //On active le tri. Par defaut, le tri est par ordre croissant
    pList2->setSortingEnabled(true);
    //On utilise les QListWidgetItem. Le tri se fera par ordre lexicale
    for (int i=0;i<20;++i)
    {
       QListWidgetItem*item = new QListWidgetItem(pList2);
       item ->setData ( 0, QVariant(i));
    }

    QWidget w;
    QHBoxLayout  hl(&w);
    hl.addWidget(pList1);
    hl.addWidget(pList2);
    w.resize(400, 400);
    w.show();
    return app.exec();
}

Comment effacer le contenu d'un QTableWidget ?
auteur : François Jaffré
Pour effacer le contenu d'un QTableWidget c'est très simple, il faut tout d'abord effacer les QTableWidgetItem qu'il contient puis effacer toutes les lignes du tableau.
//On efface les QTableWidgetItem contenu dans le tableau
tableWidget->clear();
//On efface toutes les lignes du tableau
tableWidget->setRowCount(0);


Consultez les autres F.A.Q's


Valid XHTML 1.1!Valid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.