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 :

QStandardItemModel : filtrer sur plusieurs colonnes


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 32
    Par défaut QStandardItemModel : filtrer sur plusieurs colonnes
    Bonjour,

    J'ai établit un QStandardItemModel pour stocker mes données et je souhaite filtrer cette liste sur plusieurs colonnes.
    Par exemple :
    Nom (colonne 0) : Dupond
    Prénom (colonne 1) : Jean

    J'y arrive sur une colonne mais je ne vois pas comment faire avec plusieurs colonnes... Une idée ?

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 13
    Par défaut
    Hello,

    tu peux utiliser un QSortFilterProxyModel. Tu définis le source model à ce proxy par la méthode setSourceModel().
    Ici ton source model c'est ton QStandardItemModel.
    Une fois ceci fait, tu set ce proxy comme model de ta view.
    Ensuite tu peux filter le contenu de ton modèle grace aux méthodes :
    - QSortFilterProxyModel::setFilterKeyColumn() pour définir quelle colonne tu veux filtrer (nom, prénom...)
    - QSortFilterProxyModel::setFilterRegExp() pour définir ton pattern de filtrage.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 32
    Par défaut
    Citation Envoyé par Bezu_Menez Voir le message
    - QSortFilterProxyModel::setFilterKeyColumn() pour définir quelle colonne tu veux filtrer (nom, prénom...)
    - QSortFilterProxyModel::setFilterRegExp() pour définir ton pattern de filtrage.
    C'est ce que j'ai fait pour filtrer sur la colonne "Nom" de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void OngletSaisie::filtrageNom(QString nouveauTexte)
    {
        QSortFilterProxyModel *modeleFiltre = new QSortFilterProxyModel() ;
     
        modeleFiltre->setSourceModel(m_modeleInscrits);
        modeleFiltre->setFilterKeyColumn(1) ;
        modeleFiltre->setFilterFixedString(nouveauTexte) ;
     
        vueResultats->setModel(modeleFiltre) ;
    }
    Mais si je fais la même chose avec setFilterKeyColumn(2), à quoi s'applique la méthode setFilterFixedString() ?
    Ça n'annule pas mon précédent filtre ?

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 13
    Par défaut
    Mais si je fais la même chose avec setFilterKeyColumn(2), à quoi s'applique la méthode setFilterFixedString() ?
    Ça n'annule pas mon précédent filtre ?
    Elle s'applique sur la 3ème colonne (tout index de colonne commence par 0).

    En effet cela va annuler ton précédent filtre. Je ne sais pas trop ce que tu veux faire, mais si tu comptes appliquer 2 filtres (l'un sur la 1er colonne puis l'autre sur la seconde colonne), il faut utiliser une chaine de proxys.

    Au lieu de setter le proxymodel sur ta vue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vueResultats->setModel(modeleFiltre) ;
    tu vas utiliser ce proxy comme sourcemodel() d'une nouvelle instance de QSortProxyModel. Sur cette nouvelle instance, tu vas définir le filterKeyColumn à la troisième colonne.

    Et c'est ce nouveau proxy que tu vas donner à ta vue vueResultats (car comme tu l'as remarqué dans ton précédent code, un proxy est une classe dérivée de QAbstractItemModel).
    Si je schématise ta chaine de model ca donne un truc comme ca :

    QStandardItemModel <- QSortFilterProxyModel (1) <- QSortFilterProxyModel (2) <- QAbstractItemView

    avec QSortFilterProxyModel (1) : proxy qui filtre la 1ere colonne
    avec QSortFilterProxyModel (2) : proxy qui filtre la 2eme colonne

    Bonne chance !

    Ps : remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void OngletSaisie::filtrageNom(QString nouveauTexte)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void OngletSaisie::filtrageNom(const QString & nouveauTexte)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 32
    Par défaut
    J'ai bien saisi, l'explication est très claire. Mais j'essaie déjà d'aller plus loin et de réfléchir à plus de souplesse.
    Je vais avoir au minimum 4 colonnes possible à filtrer.

    Je pense créer dans le constructeur la source, et un proxy de filtre actuel et un nouveau.

    Ensuite pour chaque slot lié à mes signaux de champs de recherche (textChanged), je définis le nouveau filtre avec comme source le filtre en cours.
    Mais la ou je bloque, c'est pour à nouveau établir le nouveau filtre comme filtre en cours (une copie ? ça risque d'être long).

    Je posterai le résultat de mes expériences dès que possible.

    Citation Envoyé par Bezu_Menez Voir le message
    Ps : remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void OngletSaisie::filtrageNom(QString nouveauTexte)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void OngletSaisie::filtrageNom(const QString & nouveauTexte)
    Oui, merci, c'est toujours mieux de bien établir ces détails car après on oublie...

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 13
    Par défaut
    J'ai pas tout compris...

    T'as une treeview avec 4 colonnes minimum. Tu associes donc un champ QLineEdit par colonne pour pouvoir associer plusieurs filtres par colonne ?
    Plutot que de créer un proxy à chaque textChanged(), tu n'as qu'à créer la chaine de proxys dans le constructeur. Chaque proxy est ainsi conservé en variable membres de ta classe.
    Chaque textChanged() viendra modifier, via la méthode setFilterFixedString(), le proxy concerné.

Discussions similaires

  1. Filtrer les doublons sur plusieurs colonnes
    Par henri228 dans le forum Conception
    Réponses: 2
    Dernier message: 07/05/2010, 22h21
  2. trier un stringgrid sur plusieurs colonnes
    Par renegade55 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 13/12/2005, 16h30
  3. Jointure avec conditions sur plusieurs colonnes
    Par ben53 dans le forum Langage SQL
    Réponses: 9
    Dernier message: 28/11/2005, 09h27
  4. Lister sur plusieurs colonnes dans état
    Par armagued dans le forum Access
    Réponses: 3
    Dernier message: 30/10/2005, 21h21
  5. Query sur plusieurs colonnes avec count(distinct...)
    Par Jeankiki dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/08/2004, 15h22

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