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 :

Affichage dynamique dans une QListView


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut Affichage dynamique dans une QListView
    Bonjour à tous !

    Alors je suis sur un projet d'annuaire/carnet d'adresses et dans ce cadre mon interface QT doit permettre différentes choses.

    L'utilisateur peut créer des contacts via une box dans laquelle il rempli différents champs (Nom, Prénom, etc ..) et l'ajoute à une QList.

    Cette liste est donc alimentée dynamiquement et j'aimerais afficher dans une QListView les noms et prénoms des contacts présents dans la liste et lors du double clic sur une des éléments de le liste, il faut afficher l’intégralité des variables de l’objet sélectionné dans une QTableView.

    Ce qui est fait :

    L'ihm globale, la QListView et QTableView, la box de saisie, l'ajout à la liste, l'objet "Contact" ;

    Où je bloque :

    Afficher les noms et prénoms dans la QListView et la mettre à jour lors de la modification de la liste ;

    Afficher toutes les valeurs d'un contact, sélectionné dans la QListView, dans la QTableView;

    Afficher le nombre de contacts dans la liste ;

    Le système de binding du C# était intéressant lorsque j'en faisait mais la c'est du c++ du coup je ne vois pas trop comment faire ..

    Niveau SIGNAL/SLOT je connais un minimum mais il y a surement des manques et niveau MVC je débute ..

    J'ai vu que je devais créer une classe héritant de QAbstractItemModel mais je suis perdu entre différentes notions et mécanismes ..

    SI quelqu'un a une idée afin de m'orienter ce serait trop gentil de sa part :p

    Le programme est un peu long, s'il faut je peux mettre des bouts de codes mais il faut que je sache quelles sont les parties pouvant vous aider à m'aider

  2. #2
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Bonjour,

    Je ne comprend pas l'intérêt d'utilise une QTableView pour afficher les détails du contact sélectionné. Pourquoi ne pas réutiliser la même vue utilisée pour la saisie d'un nouveau contact, en mode "read-only"?
    Une table view n'est rien d'autre qu'une list view avec plusieurs colonnes. Donc si le but est d'affiché un seul contact à la fois, cela ne servira à rien à mon avis.

    Sinon, il faut effectivement dérivé de QAbstractItemModel. Mais Qt fourni les classes d'aide QAbstractListModel ainsi que QAbstractTableModel qui sont déjà prévues pour faciliter l'implémentation des modèles pour QListView et QTableView. Plusieurs autres classes de modèles déjà implémentés existent aussi, tel que QStringListModel, QStandardItemModel, QFileSystemModel, QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel.

    Pour remplir la QListView, vous avez 2 possibilités. Soit hériter de QAbstractListModel et implémenter l'affichage de vos données. Si le modèle ne doit pas être modifiable, c'est assez simple en soit. L'autre possibilité est de générer une simple QStringList depuis la liste de vos contacts, est ensuite l'afficher cette liste dans la QListView par le biais d'un QStringListModel. Cela évite d'implémenter son propre modèle, mais c'est un peu du bricolage à mon avis et je ne recommande pas cette méthode. Vous trouverez ci-dessous un exemple d'implémentation d'un modèle simple héritant de QAbstractListModel.

    Héritage de QAbstractListModel
    Qt creator fourni aussi un assistant pour créer une classe de type "Qt Item model" (mon installation en en anglais, je ne sais pas quel est l'équivalent en français) en faisant clique-droit sur le projet -> ajouter nouveau... puis en sélectionnant Qt à gauche, et "Qt Item Model" sur la droite.
    Nom : 2017-11-01 13_37_42-New File.png
Affichages : 2709
Taille : 32,8 Ko
    Nom : 2017-11-01 13_47_20-Qt Item Model.png
Affichages : 2685
Taille : 32,4 Ko
    Qt Creator va alors créer une nouvelle classe avec 2 fonctions prédéfinies, rowCount() et data() qui sont les seules à implémenter.

    Voici un exemple basique:
    mylistmodel.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
    35
    36
    37
    38
    39
    40
    #ifndef MYLISTMODEL_H
    #define MYLISTMODEL_H
     
    #include <QAbstractListModel>
     
    class MyData{
    public:
        QString firstname;
        QString lastname;
        QString info1;
        QString info2;
     
        QString fullname() const{
            return firstname + " " + lastname;
        }
    };
     
    typedef QList<MyData> MyDataList;
     
    class MyListModel : public QAbstractListModel
    {
        Q_OBJECT
     
    public:
        explicit MyListModel(QObject *parent = nullptr);
     
        // Basic functionality:
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
     
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
     
        MyDataList list() const;
        void setList(const MyDataList &list);
     
    private:
     
        MyDataList m_list;
    };
     
    #endif // MYLISTMODEL_H
    mylistmodel.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
    #include "mylistmodel.h"
     
    MyListModel::MyListModel(QObject *parent)
        : QAbstractListModel(parent)
    {
    }
     
    int MyListModel::rowCount(const QModelIndex &parent) const
    {
        // For list models only the root node (an invalid parent) should return the list's size. For all
        // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
        if (parent.isValid())
            return 0;
     
        return m_list.size();
    }
     
    QVariant MyListModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
     
        int row = index.row();
        if(row < 0 || row >= m_list.size())
            return QVariant();
     
        switch(role){
            case Qt::DisplayRole:
            case Qt::EditRole: //not necessary for read-only model
                return m_list.at(row).fullname();
        }
     
        return QVariant();
    }
     
    MyDataList MyListModel::list() const
    {
        return m_list;
    }
     
    void MyListModel::setList(const MyDataList &list)
    {
        beginResetModel();
        m_list = list;
        endResetModel();
    }
    Pour ce qui est de l'affichage des infos d'un contact, il est possible d'utiliser les signaux void clicked(const QModelIndex &index) et void doubleClicked(const QModelIndex &index) afin de détecter le clique ou double-clique sur un élément de la liste, ensuite il faut récupérer l'élément grâce à son index et l'afficher dans une vue prévue à cet effet. Comme je l'ai dit je ne pense pas qu'une QTableView soit adapté pour cela.

    Au niveau du code, cela donnera quelque chose comme cela:
    mywidget.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class MyWidget : public QWidget
    {
    public:
        explicit MyWidget(QWidget *parent = 0);
        ...
    private slots:
        void contactClicked(const QModelIndex &index);
    ...
    private:
        MyListModel *m_myModel;
    ...
    };
    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
    MyWidget::MyWidget(QWidget *parent = 0)
    : QWidget(parent), ui(new Ui::MyWidget)
    {
        ui->setupUi(this);
     
        m_myModel = new MyListModel(this);
        m_myModel.setList(getContactList())
        ui->listView.setModel(m_myModel);
        connect(ui->listView, &QlistView::clicked, this, &MyWidget::contactClicked);
    }
     
    void MyWidget::contactClicked(const QModelIndex &index)
    {
        if(index < 0 || index >m_contactList.size())
            return;
        displayContact(index.row()); 
    }

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut
    Merci pour ta réponse Gojir4

    J'avais commencé à implémenter une classe héritant de QAbstractListModel, (ressemblant beaucoup à celle que tu as écrite ) mais étant donné le peu de fonctionnalité dont j'ai besoin pour ma vue je suis passé par une autre méthode.
    Mais je vais comparer nos deux codes afin de voir un peu le fonctionnement et cela me servira surement pour la suite de mon projet .

    J'ai donc effectivement utilisé la seconde méthode dont tu as parlé, (avant de voir ta réponse d'ailleurs c'est marrant:p), qui est une QStringList générée à partir de ma QList, affichée dans la QStringView via un QStringListModel et cela fonctionne plutôt bien, l'index de ma QListView est identique à celui de ma QList et je rafraîchi cette QStringList et l'applique au modèle dès changement dans la liste de contacts.

    L'affichage des détails du contact se fait en sélectionnant un contact dans la QListView, récupérant le QModelIndex, le passant en valeur d'index pour l'accès à la QList et modifiant les valeur d'affichage des QLabel du QGridLayout où sont affichés les infos du contact via les Getteur de ma classe contact. Je ne passe pas par un QTableView pour cela.

    L'utilisation de la QTableView va être utilisée pour afficher un regroupement de certains contacts dans un "carnet d'affaire" qui sert à regrouper et à voir toutes les infos de ces contacts sur la même vue.
    Je n'ai pas encore travailler sur cette partie, je m'y met aujourd'hui.

  4. #4
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Dans ce cas (affichage de plusieurs contacts dans un QTableView), l'idéal serait en fait d'implémenter directement un classe qui hérite de QAbstractTableModel, ensuite ce modèle pourra être utilisé aussi bien pour un QListView que pour une QTableView. Cependant ce n'est pas bien plus compliqué que l'implémentation d'un QAbstractListModel, il faut simplement ajouter la fonction "columnCount()" ainsi que modifier l'implémentation de la fonction "data()".

    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
    QVariant MyModel::data(const QModelIndex &index, int role) const
    {
    ...
        if(role == Qt::DisplayRole || role == Qt::EditRole)
            switch(index.column()){
                 case 0: return m_list.at(index.row).firstname();
                 case 1: return m_list.at(index.row).lastname();
                 case 2: return m_list.at(index.row).email();
            }
    ...
    }
     
    int MyModel::columnCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return NB_COLUMN;
    }
    Au besoin je peux partager un code plus détaillé. J'ai développé il y a quelque temps un modèle justement pour afficher une liste de contacts (clients) dans une QTableView. Par contre c'est un peu complexe car le modèle permet aussi de faire du tri et du filtrage, en utilisant un QSortFilterProxyModel, du drag and drop entre plusieurs QTableView, est compatible avec QML, éditable et permet de restaurer les éléments de la listes qui ont été préalablement supprimé. Néanmoins je peux simplifier le code et le partager si cela vous intéresse.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut
    Et bien je t'avoue que je suis preneur pour ton partage de code

    Après la partie filtrage et drag n drop m’intéresse également car je n'en ai pas fait lors de mes différents projet et ce pourra bien m'aider a comprendre le principe de fonctionnement ^^

  6. #6
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Voici (enfin) le code comme promis. Il m'as fallu dépoussiérer tout ça :D

    J'ai mis le projet dans un zip, en pièce jointe, sinon cela aurait-été illisible sur un post.

    C'est un simple projet avec un widget qui montre comment utiliser le modèle avec QListView et QTableView, comment filtrer ou trier les données et comment activer le drag only, drag & drop ou drop only.

    Tu trouveras 2 classes, Customer et CustomerModel.
    Customer est vraiment très basique, nom, prénom, entreprise et e-mail. Mais il est facile d'ajouter ce qui est nécessaire.
    CustomerModel implémente le modèle pour gérer et afficher une liste de Customer.

    Note que c'est ma première implémentation du drag & drop donc je ne garantis pas que cela soit dépourvu de bugs, comme pour le reste du projet d'ailleurs.

    Il n'y a pas beaucoup de commentaires dans le code mais n'hésite pas à poster tes questions ici ou en mp en cas de besoin.
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. [AJAX] Affichage dynamique dans une pop-up
    Par benoit-v dans le forum AJAX
    Réponses: 0
    Dernier message: 03/12/2014, 11h51
  2. [Débutant] Affichage dynamique dans une form principale
    Par diblasio dans le forum C#
    Réponses: 4
    Dernier message: 12/04/2012, 21h06
  3. Affichage dynamique dans une JFrame
    Par crocodingo dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 17/03/2009, 18h27
  4. Affichage dynamique d'une requete Access dans Excel
    Par alex830001 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 18/06/2008, 16h54
  5. Affichage et alignement vertical dynamique dans une page lors d'un clic
    Par Invité dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/05/2008, 22h08

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