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

Vue hybride

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    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 émérite

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    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.

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    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 averti
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    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 émérite

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    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.

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    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é

+ 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