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 :

Filtrer une QTreeView

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut Filtrer une QTreeView
    Bonjour,
    Je cherche à filtrer les éléments d'une QTreeView en sélectionnant les valeurs à filtrer dans une QComboBox. J'ai tenté de suivre l'exemple "Basic Sort/Filter Model" mais j'avoue que je n'y ai pas compris grand chose
    J'ai donc essayé sur le petit exemple (simple) qui suit pour tenter de comprendre comment ça fonctionne :
    - 3 colonnes dans la QTreeView ("name", "country" et "Players"). Dans la colonne "Players" il y a un nombre de joueurs.
    - 1 QComboBox avec quatre valeurs ("All Players", "10 players", "6 players", "2 players").

    Lorsque je sélectionne "6 players" dans la QComboBox, je veux filtrer la QTreeView et n'afficher que les lignes qui ont la valeur "6" dans la colonne "Players" .... mais j'y arrive pas : il ne se passe rien lorsque je sélectionne une valeur dans la QComboBox.

    Je joins le code de l'exemple

    D'avance merci pour votre aide

    Hervé


    main.cpp
    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
     
    #include <QtGui>
    #include "UIFilter.h"
     
    void addPlayTable(QAbstractItemModel *p_model,
                      const int p_idx,
                      const QString &p_name,
                      const QString &p_country,
                      const QString &p_players)
    {
        p_model->insertRow(p_idx);
     
        p_model->setData(p_model->index(p_idx, 0), p_name);
        p_model->setData(p_model->index(p_idx, 1), p_country);
        p_model->setData(p_model->index(p_idx, 2), p_players);
    }
     
    QAbstractItemModel *createPlayModel(QObject *parent)
    {
        QStandardItemModel *l_model = new QStandardItemModel(0, 3, parent);
        l_model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
        l_model->setHeaderData(1, Qt::Horizontal, QObject::tr("Country"));
        l_model->setHeaderData(2, Qt::Horizontal, QObject::tr("Players"));
     
     
        addPlayTable(l_model, 0, "Montpellier", "France", "6");
        addPlayTable(l_model, 1, "Paris", "France", "10");
        addPlayTable(l_model, 2, "London", "United Kingdom", "15");
        addPlayTable(l_model, 3, "New York", "USA", "7");
     
        return l_model;
    }
     
    int main(int argc, char *argv[])
    {
         QApplication app(argc, argv);
         UIFilter filter;
         filter.setSourceModel(createPlayModel(&filter));
         filter.show();
         return app.exec();
    }
    UIFilter.cpp
    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    #include <QtGui/QSortFilterProxyModel>
    #include <QtGui/QVBoxLayout>
    #include <QtGui/QTreeView>
    #include <QtGui/QGroupBox>
    #include <QtGui/QComboBox>
    #include <QtCore/QtDebug>
     
    #include "UIFilter.h"
     
    UIFilter::UIFilter(QWidget *parent) : QWidget(parent)
    {
        m_proxyModel = new QSortFilterProxyModel;
        m_proxyModel->setDynamicSortFilter(true);
     
        QGroupBox *l_playGroupBox = new QGroupBox(tr("Players by countries"));
     
        m_playTreeView = new QTreeView(this);
        m_playTreeView->setRootIsDecorated(false);
        m_playTreeView->setAlternatingRowColors(true);
        m_playTreeView->setSortingEnabled(true);
     
        m_playTreeView->resizeColumnToContents(0);
        m_playTreeView->resizeColumnToContents(1);
        m_playTreeView->resizeColumnToContents(2);
     
        m_playTreeView->sortByColumn(1, Qt::AscendingOrder);
     
        QVBoxLayout *l_vbLayout1 = new QVBoxLayout;
        l_vbLayout1->addWidget(m_playTreeView);
        l_playGroupBox->setLayout(l_vbLayout1);
     
     
        QGroupBox *l_playersGroupBox = new QGroupBox(tr("Players"));
     
        m_playersComboBox = new QComboBox;
        m_playersComboBox->addItem(tr("All players"), QRegExp::RegExp);
        m_playersComboBox->addItem(tr("10 players"), QRegExp::RegExp);
        m_playersComboBox->addItem(tr("6 players"), QRegExp::RegExp);
        m_playersComboBox->addItem(tr("2 players"), QRegExp::RegExp);
     
        QVBoxLayout *l_vbLayout2 = new QVBoxLayout;
        l_vbLayout2->addWidget(m_playersComboBox);
        l_playersGroupBox->setLayout(l_vbLayout2);
     
        qDebug() << "Combo current index : " << m_playersComboBox->currentIndex();
        qDebug() << "Combo selection : " << m_playersComboBox->currentText();
     
        QGridLayout *l_mainLayout = new QGridLayout;
        l_mainLayout->addWidget(l_playGroupBox,0,0);
        l_mainLayout->addWidget(l_playersGroupBox,0,1,Qt::AlignTop);
        l_mainLayout->setSizeConstraint(QLayout::SetFixedSize);
     
        setLayout(l_mainLayout);
     
        connect(m_playersComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(OnComboChanged()));
    }
     
    UIFilter::~UIFilter() {}
     
    void UIFilter::setSourceModel(QAbstractItemModel *p_model)
    {
        m_proxyModel->setSourceModel(p_model);
        m_playTreeView->setModel(p_model);
    }
     
    void UIFilter::OnComboChanged()
    {
        qDebug() << "Function OnComboChanged() called";
        qDebug() << "Combo current index : " << m_playersComboBox->currentIndex();
        qDebug() << "Combo selection : " << m_playersComboBox->currentText();
     
        QString l_comboSelection = m_playersComboBox->currentText();
     
        QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(m_playersComboBox->itemData(m_playersComboBox->currentIndex()).toInt());
        Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
     
        QRegExp regExp("^(\\d{1,2})\\s.*$", caseSensitivity, syntax);
        if (l_comboSelection.contains(regExp))   {
            QString l_numberOfPlayers = regExp.cap(1);
            qDebug() << "Contains true : " + l_numberOfPlayers;
        } else {
            qDebug() << "Contains false";
        }
     
        m_proxyModel->setFilterRegExp(regExp);
     }
    UIFilter.h
    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
     
    #ifndef UIFILTER_H
    #define UIFILTER_H
     
    #include <QtGui/QWidget>
     
    class QSortFilterProxyModel;
    class QTreeView;
    class QComboBox;
    class QAbstractItemModel;
     
    class UIFilter : public QWidget
    {
        Q_OBJECT
     
    public:
        UIFilter(QWidget *parent = 0);
        ~UIFilter();
     
        void setSourceModel(QAbstractItemModel *p_model);
     
    private slots:
        void OnComboChanged();
     
    private:
        QSortFilterProxyModel *m_proxyModel;
     
        QTreeView *m_playTreeView;
        QComboBox *m_playersComboBox;
    };
    #endif // UIFILTER_H

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Points : 969
    Points
    969
    Par défaut
    Lorsque tu fais ton connect entre ta combobox et ta classe, il y a une erreur.

    En effet, dans le connect, le signal et le slot utilisé doivent toujours avoir exactement les mêmes arguments.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(m_playersComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(OnComboChanged()));
    Ici, il faudrait que tu change la définition de ton slot :
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OnComboChanged(QString)
    Le qstring passé en paramètre sera celui émis par ton signal, soit le texte du nouvel index de ta comboBox.

    G.

    PS : Il y a peut être d'autres erreurs, je n'ai pas fouillé plus que ça.
    Un problème avec Qt ? Vous trouverez votre réponse ici : http://doc.trolltech.com/4.6/overviews.html
    En français (traduction réalisée par l'équipe Qt de DVP) : http://qt.developpez.com/doc/4.6/vues-d-ensemble/

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Bonjour,
    Je n'avais pas compris l'importance de la concordance des types dans les paramètres des méthodes appelées dans le connect.

    Malheureusement ceci ne corrige pas le problème, même si je récupère bien dans le paramètre de la méthode OnComboChanged, la valeur qui est sélectionnée dans la combo, la liste n'est pas filtrée.

    Merci pour votre contribution.

    Hervé

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    En ajoutant une deuxième QTreeView (1 source et 1 proxy) comme dans l'exemple, il y a du changement : la QTreeView proxy est filtrée ... mais ce n'est pas ce que je veux faire. Je ne veux qu'une seule QTreeView, afficher les éléments dans ce Widget, filtrer et rafraichir dans ce même Widget.

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Points : 969
    Points
    969
    Par défaut
    N'est ce pas juste un problème de mise à jour de l'affichage de l'arbre ?
    As tu essayé de faire un update(monModel) ? Ou un clear() puis de recharger ton modele ?

    Je n'ai pas trop touché à ce genre de composant, mais il est possible qu'il faille recharger le modele si celui si a été modifé.

    G.

    Edit : c'est même quasiment sûr, car ils disent que la fonction "setModel(monModele)" crée un nouveau model et l'affiche, et qu'il ne faut pas oublie de supprimer l'ancien. En gros, je pense que ça affiche une copie du modele au moment ou tu l'affiches.
    Refaire un setModel(...) après modification serait sans doute la solution. N'oublie cependant pas de supprimer les anciens modeles.
    Un problème avec Qt ? Vous trouverez votre réponse ici : http://doc.trolltech.com/4.6/overviews.html
    En français (traduction réalisée par l'équipe Qt de DVP) : http://qt.developpez.com/doc/4.6/vues-d-ensemble/

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Bonsoir,
    Merci pour votre post mais je ne m'en sors pas ...
    En ajoutant une autre QTreeView (proxy) comme dans l'exemple, il y a filtrage mais toutes les lignes sont supprimées même celles qui ne satisfont pas à la condition du filtre. Je ne parviens pas à filtrer sur les valeurs d'une colonne.

    Si quelqu'un a un exemple, je suis preneur parce que là je suis un peu perdu.

    D'avance merci

    Hervé

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Bonsoir,
    Bon, j'arrive à filtrer les éléments d'une colonne. L'erreur venait de la RegExp qui est passée au proxy model :

    Alors que je passais une règle de filtrage ("^(\\d{1,2})\\s.*$") à la méthode setFilterRegExp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    QRegExp regExp("^(\\d{1,2})\\s.*$", caseSensitivity, syntax);
    if (l_comboSelection.contains(regExp))   {
        QString l_numberOfPlayers = regExp.cap(1);
        qDebug() << "Contains true : " + l_numberOfPlayers;
    } else {
        qDebug() << "Contains false";
    }
     
    m_proxyModel->setFilterRegExp(regExp);
    il faut tout simplement passer au proxy model une chaîne de caractères à rechercher et l'envoyer au proxy model :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    QString m_filterPattern;
     
    QRegExp regExp("^(\\d{1,2})\\s.*$", Qt::CaseInsensitive, QRegExp::RegExp);
    if (p_comboSelection.contains(regExp))   {
        m_filterPattern = regExp.cap(1);
        qDebug() << "Number of selected players : " + m_filterPattern;
    } else {
        m_filterPattern = "";
    }
    QRegExp regExp2(m_filterPattern, Qt::CaseInsensitive, QRegExp::RegExp);
    proxyModel->setFilterRegExp(regExp2);
    Je pense que le proxy model se charge de construire la règle de filtrage à partir du type de RegExp passé en paramètres (Qt::RegExp)

    Mais il me faut toujours avoir une QTreeView source et une QTreeView proxy dans laquelle les données apparaissent comme filtrées

    Une solution consiste à stocker les données dans une QTreeView source mais de ne pas afficher le Widget et de n'afficher que le QTreeView proxy

    Que pensez-vous de cette solution ?

    Merci pour vos conseils

    Hervé

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Bonsoir,
    J'ai fini par y arriver en m'inspirant de l'exemple "Custom Sort/Filter Model" !!! J'ai étendu la classe QSortFilterProxyModel puis dans cette classe (QTreeViewFilterProxyModel) j'ai défini une méthode setFilterColumn qui me permet de stocker dans une QMap la liste des couples (id de colonne sélectionnée, QRegExp à appliquer à la colonne) et j'ai redéfini la méthode filterAcceptsRow pour appliquer les filtres qui sont stockés dans la QMap.

    Je joins le code, ça pourra peut être aider quelqu'un ;-)

    main.cpp
    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
     
    #include <QtGui>
    #include "UIFilter.h"
     
    void addPlayers(QAbstractItemModel *p_model,
                    const int p_idx,
                    const QString &p_name,
                    const QString &p_country,
                    const QString &p_players)
    {
        p_model->insertRow(p_idx);
     
        p_model->setData(p_model->index(p_idx, 0), p_name);
        p_model->setData(p_model->index(p_idx, 1), p_country);
        p_model->setData(p_model->index(p_idx, 2), p_players);
    }
     
    QAbstractItemModel *createPlayersModel(QObject *parent)
    {
        QStandardItemModel *l_model = new QStandardItemModel(0, 3, parent);
        l_model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
        l_model->setHeaderData(1, Qt::Horizontal, QObject::tr("Country"));
        l_model->setHeaderData(2, Qt::Horizontal, QObject::tr("Players"));
     
        addPlayers(l_model, 0, "Montpellier", "France", "6");
        addPlayers(l_model, 1, "Paris", "France", "10");
        addPlayers(l_model, 2, "London", "United Kingdom", "15");
        addPlayers(l_model, 3, "New York", "USA", "7");
        addPlayers(l_model, 4, "Rome", "Italie", "6");
     
        return l_model;
    }
     
    int main(int argc, char *argv[])
    {
         QApplication app(argc, argv);
         UIFilter filter;
         filter.setSourceModel(createPlayersModel(&filter));
         filter.show();
         return app.exec();
    }
    UIFilter.h
    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
     
    #ifndef UIFILTER_H
    #define UIFILTER_H
     
    #include <QtGui/QWidget>
     
    class QTreeView;
    class QComboBox;
    class QAbstractItemModel;
    class QTreeViewFilterProxyModel;
     
    class UIFilter : public QWidget
    {
        Q_OBJECT
     
    public:
        UIFilter(QWidget *parent = 0);
        ~UIFilter();
     
        void setSourceModel(QAbstractItemModel *p_model);
     
    private slots:
        void OnComboCountryChanged(const QString &p_comboSelection);
        void OnComboPlayersChanged(const QString &p_comboSelection);
     
    private:
        QTreeViewFilterProxyModel *m_proxyModel;
     
        QTreeView *m_sourceTreeView;
        QTreeView *m_proxyTreeView;
        QComboBox *m_playersComboBox;
        QComboBox *m_countryComboBox;
    };
    #endif // UIFILTER_H
    UIFilter.cpp
    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    #include <QtGui/QTreeView>
    #include <QtGui/QGroupBox>
    #include <QtGui/QComboBox>
    #include <QtGui/QVBoxLayout>
    #include <QtCore/QtDebug>
     
    #include "QTreeViewFilterProxyModel.h"
    #include "UIFilter.h"
     
    UIFilter::UIFilter(QWidget *parent) : QWidget(parent)
    {
        m_proxyModel = new QTreeViewFilterProxyModel(this);
        m_proxyModel->setDynamicSortFilter(true);
     
        m_sourceTreeView = new QTreeView;
     
        QGroupBox *l_proxyGroupBox = new QGroupBox(tr("Players by countries"));
        QGroupBox *l_playersGroupBox = new QGroupBox(tr("Select to apply a filter"));
     
        m_proxyTreeView = new QTreeView;
        m_proxyTreeView->setRootIsDecorated(false);
        m_proxyTreeView->setAlternatingRowColors(true);
        m_proxyTreeView->setModel(m_proxyModel);
        m_proxyTreeView->setSortingEnabled(true);
        m_proxyTreeView->resizeColumnToContents(0);
        m_proxyTreeView->resizeColumnToContents(1);
        m_proxyTreeView->resizeColumnToContents(2);
     
        m_countryComboBox = new QComboBox;
        m_countryComboBox->addItem(tr("All country"));
        m_countryComboBox->addItem(tr("France"));
        m_countryComboBox->addItem(tr("Italie"));
     
        m_playersComboBox = new QComboBox;
        m_playersComboBox->addItem(tr("All players"));
        m_playersComboBox->addItem(tr("10 players"));
        m_playersComboBox->addItem(tr("6 players"));
        m_playersComboBox->addItem(tr("2 players"));
     
        connect(m_countryComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(OnComboCountryChanged(const QString &)));
        connect(m_playersComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(OnComboPlayersChanged(const QString &)));
     
        // Display only the proxy view
        QVBoxLayout *l_vbLayout1 = new QVBoxLayout;
        l_vbLayout1->addWidget(m_proxyTreeView);
        l_proxyGroupBox->setLayout(l_vbLayout1);
     
        QVBoxLayout *l_vbLayout2 = new QVBoxLayout;
        l_vbLayout2->addWidget(m_countryComboBox);
        l_vbLayout2->addWidget(m_playersComboBox);
        l_playersGroupBox->setLayout(l_vbLayout2);
     
        QGridLayout *l_mainLayout = new QGridLayout;
        l_mainLayout->addWidget(l_proxyGroupBox,0,0);
        l_mainLayout->addWidget(l_playersGroupBox,0,1,Qt::AlignTop);
        l_mainLayout->setSizeConstraint(QLayout::SetFixedSize);
        setLayout(l_mainLayout);
     
        m_proxyTreeView->sortByColumn(0,Qt::AscendingOrder);
        m_countryComboBox->setCurrentIndex(0);
        m_playersComboBox->setCurrentIndex(0);
    }
     
    UIFilter::~UIFilter()
    {
        delete m_proxyModel;
        delete m_sourceTreeView;
        delete m_proxyTreeView;
        delete m_countryComboBox;
        delete m_playersComboBox;
    }
     
    void UIFilter::setSourceModel(QAbstractItemModel *p_model)
    {
        m_proxyModel->setSourceModel(p_model);
        m_sourceTreeView->setModel(p_model);
    }
     
    void UIFilter::OnComboCountryChanged(const QString &p_comboSelection)
    {
        qDebug() << "";
        qDebug() << "++ Function OnComboCountryChanged() called";
        qDebug() << "Combo current index : " << m_countryComboBox->currentIndex();
        qDebug() << "Combo selection : " << m_countryComboBox->currentText();
     
        QString l_filterPattern;
     
        if (p_comboSelection.contains("All country"))   {
            l_filterPattern = "";
        } else {
            l_filterPattern = p_comboSelection;
        }
     
        QRegExp l_regExp(l_filterPattern, Qt::CaseInsensitive, QRegExp::RegExp);
        m_proxyModel->setFilterColumn(1, l_regExp);
     }
     
    void UIFilter::OnComboPlayersChanged(const QString &p_comboSelection)
    {
        qDebug() << "";
        qDebug() << "++ Function OnComboPlayersChanged() called";
        qDebug() << "Combo current index : " << m_playersComboBox->currentIndex();
        qDebug() << "Combo selection : " << m_playersComboBox->currentText();
     
        QString l_filterPattern;
     
        if (p_comboSelection.contains("All players"))   {
            l_filterPattern = "";
        } else {
            QRegExp regExp("^(\\d{1,2})\\s.*$", Qt::CaseInsensitive, QRegExp::RegExp);
            if (p_comboSelection.contains(regExp))   {
                l_filterPattern = regExp.cap(1);
                qDebug() << "Number of selected players : " + l_filterPattern;
            } else {
                l_filterPattern = "";
            }
        }
        QRegExp l_regExp(l_filterPattern, Qt::CaseInsensitive, QRegExp::RegExp);
        m_proxyModel->setFilterColumn(2, l_regExp);
    }
    QTreeViewFilterProxyModel.h
    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
     
    #ifndef QTREEVIEWFILTERPROXYMODEL_H
    #define QTREEVIEWFILTERPROXYMODEL_H
     
    #include <QtGui/QSortFilterProxyModel>
    #include <QtCore/QMap>
     
    class QModelIndex;
     
    class QTreeViewFilterProxyModel : public QSortFilterProxyModel
    {
        Q_OBJECT
     
    public:
        QTreeViewFilterProxyModel(QObject *parent);
        ~QTreeViewFilterProxyModel();
     
        void setFilterColumn(int p_columnId, const QRegExp p_regExp);
     
    protected:
        bool filterAcceptsRow(int p_sourceRow, const QModelIndex &p_sourceParent) const;
     
    private:
        QMap<int,QRegExp>   m_filterMap;
    };
    #endif // QTREEVIEWFILTERPROXYMODEL_H
    QTreeViewFilterProxyModel.cpp
    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
     
    #include <QtGui/QSortFilterProxyModel>
    #include <QtCore/QModelIndex>
    #include <QtCore/QRegExp>
    #include <QtCore/QtDebug>
     
    #include "QTreeViewFilterProxyModel.h"
     
     
    QTreeViewFilterProxyModel::QTreeViewFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {}
     
    QTreeViewFilterProxyModel::~QTreeViewFilterProxyModel() {}
     
    void QTreeViewFilterProxyModel::setFilterColumn(int p_columnId, const QRegExp p_regExp)
    {
        qDebug() << "";
        qDebug() << "-- Function setFilterColumn() called";
        qDebug() << "Column index : " << p_columnId;
        qDebug() << "Filter : " << p_regExp.cap(0);
     
        // if exist, remove the old RegExp stored in the map
        if (m_filterMap.contains(p_columnId))   {
            qDebug() << "Remove from map for column index : " << p_columnId;
            m_filterMap.remove(p_columnId);
        }
        // insert the new RegExp in the map
        qDebug() << "Insert into map for column index : " << p_columnId;
        m_filterMap.insert(p_columnId, p_regExp);
     
        qDebug() << "m_filterMap size : " << m_filterMap.size();
     
        // Select the column to filter
        setFilterKeyColumn(p_columnId);
    }
     
    bool QTreeViewFilterProxyModel::filterAcceptsRow(int p_sourceRow, const QModelIndex &p_sourceParent) const
    {
        qDebug() << "";
        qDebug() << "-- Function filterAcceptsRow() called";
        qDebug() << "Source row index : " << p_sourceRow;
     
        bool l_bool=true;
     
        if (m_filterMap.size() != 0)
        {
            QMap<int, QRegExp>::const_iterator iter = m_filterMap.constBegin();
            while (iter != m_filterMap.constEnd()) {
                QModelIndex index = sourceModel()->index(p_sourceRow, iter.key(), p_sourceParent);
                if (!sourceModel()->data(index).toString().contains(iter.value()))   {
                    l_bool=false;
                    qDebug() << "Filtered item value : " << sourceModel()->data(index).toString();
                } else {
                    qDebug() << "Item value not filtered : " << sourceModel()->data(index).toString();
                }
                ++iter;
            }
        }
     
        return l_bool;
    }
    Si vous avez des remarques et/ou des améliorations à proposer, je suis preneur.

    Bonne soirée

    Hervé

    PS : Dans le destructeur de la classe UIFilter.cpp, je détruis explicitement les membres (Widgets) de cette classe. J'aimerais bien savoir si c'est une bonne pratique ou s'il est préférable de laisser le parent s'en charger ?

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

Discussions similaires

  1. Impossibilité de filtrer une liste déroulante
    Par lito74 dans le forum Access
    Réponses: 12
    Dernier message: 27/02/2006, 11h03
  2. [C#] Filtrer une table
    Par diaboloche dans le forum ASP.NET
    Réponses: 8
    Dernier message: 05/12/2005, 15h17
  3. Comment filtrer une TListBox ?
    Par jmjmjm dans le forum Composants VCL
    Réponses: 9
    Dernier message: 17/11/2005, 13h08
  4. Filtrer une requete avec une variable array
    Par hugo69 dans le forum Requêtes
    Réponses: 7
    Dernier message: 04/11/2005, 14h33
  5. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25

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