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 Quick Discussion :

Créer une ListView dynamique avec une propriété contextuelle


Sujet :

Qt Quick

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut Créer une ListView dynamique avec une propriété contextuelle
    Bonjour,

    Je cherche à faire une ListView dynamique basée sur une contex property. J'ai regardé l'exemple de la doc pour faire une ListView dynamique. Il suffit d'utiliser append et remove au model. Le problème étant que mon modèle est une context property, donc on ne peut pas la modifier avec append et remove. C'est là que je doute de la marche à suivre:
    -Faut-il mieux modifier ce qu'envoie la context property et recharger la ListView à chaque modification?
    -Faut-il mieux utiliser un autre système? J'ai lu sur internet qu'on pouvait utiliser des pointeurs ou des signaux et slots. Malheureusement, il n'y avait pas d'exemples avec...
    C'est pour un affichage de chemin vers des dossiers. Au chargement, la listview récupère les dossiers rentrés dans les précédentes sessions (enregistrés dans le registre par QSettings). Il peut ajouter un chemin, auquel cas il faut qu'il s'affiche dans la listview. Il peut supprimer un chemin de la listview. C'est là que je me suis demandé s'il fallait directement enregistrer les chemins dans le registre et mettre à jour la listview (puisque la context property change), ou faire autrement.

    Merci de votre aide.

    Cordialement

  2. #2
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonjour,

    Il me semblait avoir essayé ce genre de chose, et que c'était possible de modifier le modèle.
    Avez-vous regardé ceci (QtQuick 1.0, mais c'est à mon avis toujours valide pour QtQuick 2.2) ? http://christophe-dumez.developpez.c...ele-liste-cpp/
    De mémoire, avec cette approche, le modèle créé depuis le C++ et placé en propriété contextuelle n'est pas read-only.
    Vous pouvez également sous-classer directement QAbstractListModel en y respectant les indications de http://doc.qt.io/qt-5/qabstractitemm...ml#subclassing si vous avez vraiment des besoins spécifiques.

    Bonne journée,
    Louis

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Avez-vous regardé ceci (QtQuick 1.0, mais c'est à mon avis toujours valide pour QtQuick 2.2) ? http://christophe-dumez.developpez.c...ele-liste-cpp/
    De mémoire, avec cette approche, le modèle créé depuis le C++ et placé en propriété contextuelle n'est pas read-only.
    Avec cette approche, on peut modifier le modèle AVANT de la transmettre à la ListView. Mais elle ne propose pas de mises à jour une fois que la listview est chargée. Là, en clair, au lieu de créer une liste d'objets dans le QML, on la crée dans le C++. Moi ce qui m'intéresse plus, c'est d'apporter des modifications au modèle alors que la Listview est déjà affichée et par la suite utiliser le nouveau modèle dans la ListView.

    Vous pouvez également sous-classer directement QAbstractListModel en y respectant les indications de http://doc.qt.io/qt-5/qabstractitemm...ml#subclassing si vous avez vraiment des besoins spécifiques.
    Est-ce que ça veut bien dire de refaire moi-même la classe ListView de façon à faire ce qui m'intéresse? Si c'est ça, je pense pas avoir tant de besoins que ça. Là ce serait sortir un bazooka pour tuer une fourmis ^^

  4. #4
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Si vous spécialisez le ListModel proposé en ajoutant ceci :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public slots:
        void append(const QString &name, const QString &size)
        {
            appendRow(new FruitItem(name, size, this));
        }

    En théorie, dans le QML, avec cette approche, vous devriez pouvoir faire :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    model.append("Apple", "medium").

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Aaah d'accord. Je vais tester ça mais ça risque de me prendre du temps étant donné qu'il y a beaucoup de choses que je ne connais pas dans ce code et en particulier la fonction setRoleNames qui n'existe plus dans la version actuelle de Qt. Il faut que j'épluche tout le code pour savoir que garder et que changer.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Je suis en train de lire la documentation sur l'architecture MVC de Qt et je me heurte à une question mineure: a quoi sert le rôle des information dans un modèle? J'ai beau chercher, je ne trouve rien de clair sur le sujet. Dans ma tête, avec l'index on peut retrouver l'information voulue mais dans la doc, il donnent un exemple où la fonction data est appelée et elle prend deux arguments: l'index et le rôle. Mais je ne vois pas l'intérêt de ce rôle. Est-ce que vous pouvez m'éclairer?
    Je suis en train de regarder si un QStringListModel ne pourrait pas répondre à mon besoin.

    Merci de votre aide.

  7. #7
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 107
    Points : 189
    Points
    189
    Par défaut
    Bonsoir,
    En gros et en reprenant l'exemple d'amnell, name et size sont 2 rôles. Quant à l'index, c'est la ligne du ListModel.

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Euh. Je comprends plus là. Dans la doc, le rôle est présenté comme une variable prenant comme valeurs:

    Qt::DisplayRole 0 Les données-clés à rendre sous la forme de texte. (QString)
    Qt::DecorationRole 1 Les données à rendre comme décoration sous la forme d'une icône. (QColor, QIcon ou QPixmap)
    Qt::EditRole 2 Les données d'un formulaire convenant pour l'édition dans un éditeur. (QString)
    Qt::ToolTipRole 3 Les données affichées dans l'infobulle de l'item. (QString)
    Qt::StatusTipRole 4 Les données affichées dans la barre de statut. (QString)
    Qt::WhatsThisRole 5 Les données affichées pour l'item dans le mode « What's This? ». (QString)
    Qt::SizeHintRole 13 L'indice de taille pour l'item qui sera fourni aux vues. (QSize)

    Par exemple pour size, alors son rôle sera SizeHintRole (je pense hein, j'en sais rien). Je comprends par pourquoi size serait un rôle. Pouvez-vous développer votre réponse?

  9. #9
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    Si vous regardez dans la déclaration de classe, vous trouverez ceci :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class FruitItem : public ListItem
    {
      Q_OBJECT
     
    public:
      enum Roles {
        NameRole = Qt::UserRole+1,
        SizeRole,
        PriceRole
      };

    En gros, il y a un nombre donné de rôles prédéfinis, et les rôles qui vous permettent de stocker vos propres données doivent être définis à partir de Qt::UserRole. La méthode data() permet de récupérer les valeurs associées à chacune de vos données par le biais d'identificateurs, les rôles. Est-ce que cela répond à votre question ?

    Bonne soirée,
    Louis

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Je pense avoir à peu près compris. Mais alors c'est quoi l'intérêt d'avoir des rôles en plus de l'index?
    Dans l'exemple on a pricerole et sizerole mais on peut très bien se débrouiller juste avec l'index non?
    Je veux dire que dans une application, quand on demande on info, on a besoin que de l'index, je vois pas l'intérêt du rôle.

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Ah je pense avoir compris, dites moi si je me trompe:
    "Les éléments dans un modèle peuvent remplir plusieurs rôles pour les autres composants, autorisant différents types de données à être fournis dans différentes situations."
    ça voudrait dire que lorsque j'appelle une donnée, suivant la situation, je peut lui donner soit un displayrole soit un decorationrole par exemple.
    Dans leur exemple, la donnée rouge peut être appelée en tant que texte (displayrole) et en tant que couleur (decorationrole). Sauf que je n'arrive pas à imaginer le code associé. En effet, j'imagine que dans mon délégate, j'appelle la donnée "rouge" avec un index et je lui dit "color: donnée[i]" et "text:donnée[i]".
    C'est pour ça que je vois pas l'intérêt du rôle....

  12. #12
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    C'est à moitié correct. L'identificateur est en fait le rôle. En reprenant l'exemple d'une liste de fruits :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [Fruit 1 : name = "Pomme", size = "52x39", price = "1.5"]
    [Fruit 2 : name = "Poire", size = "51x29", price = "2.5"]
    [Fruit 3 : name = "Pêche", size = "57x35", price = "1.0"]
    Ici, on a trois éléments, et chaque élément contient trois rôles permettant de stocker les informations associées à chaque entrée : "name", "size" et "price" :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    enum Roles {
        NameRole = Qt::UserRole+1,
        SizeRole,
        PriceRole
    };

    Les rôles agissant comme identificateurs, ils permettent de récupérer l'information que l'on souhaite depuis une entrée de la liste. Par exemple, pour récupérer le nom du 2e fruit, on ferait QString name = data(index(1), NameRole).toString();. En QML, hors d'un delegate, ce serait text: mylist[1].name tandis que dans un delegate (pour une ListView ayant model: mylist), seulement text: name.

    De mémoire, les rôles par défaut permettent aux QListView (Qt Widgets) d'afficher les implémentations de QAbstractListModel. Un DisplayRole devrait permettre d'afficher le texte, par exemple. Cependant, il s'agit là d'une utilisation pour le module Qt Widgets ; vu que vous codez avec QML, vous n'avez en théorie pas besoin des rôles par défaut, étant donné qu'il vous est possible d'utiliser la forme que j'ai donnée ci-dessus.

    Bonne soirée,
    Louis

  13. #13
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    D'accord, je pense avoir compris. En fait, le rôle devient important à partir du moment où on a des objets complexes. Par exemple, un objet contenant 3 QString. Maintenant si j'utilise un modèle QStringListModel, qui accepte en entrée une QStringList, le rôle devient superflu (on l'indiquera uniquement pour la forme). Est-ce que j'ai raison?

  14. #14
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    Étant donné qu'il n'y a besoin de stocker que des QString, dans ce cas oui. Cela dit, je ne sais pas si vous pourrez utiliser mylist[i] tout simplement avec du QML et un QStringListModel, je n'ai jamais essayé. Si cela ne fonctionne pas, le fait d'avoir un unique rôle serait la solution.

    Bonne soirée,
    Louis

  15. #15
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut


    J'ai eu l'occasion de chercher différents moyens de dialoguer entre mon code "principal" (en ce qui me concerne Python) et QML.
    J'ai fait un bref topo, de ce que l'on peut faire en Python : http://www.developpez.net/forums/blo...-document-qml/ (enfin ce que j'ai trouvé pour le moment )

    Si j'ai bien compris ton besoin, la fonction test devrait pouvoir t'aider :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @pyqtSlot(QVariant)
    def test(self, ctx):
            txt = "Test by contextProperty"
            ctx.setContextProperty("retour", txt)


    En gros, dès le lancement du programme, je passe
    • en property une classe qui contiendra les fonctions dont j'ai besoin ;
    • en property engine.rootContext() ce qui me permettra par la suite de repasser dès que nécessaire setContextProperty avec comme argument l'objet voulu et de l'exploiter comme je le souhaite dans mon document QML.


    En espérant que cela puisse t'aider, même si ce n'est pas en C++ (à toi de faire la conversion)

    ++

    J

  16. #16
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Merci, ça marche. J'ai sous-classé QAbstractListModel et ça a l'air de fonctionner. Du moins, j'ai réussi d'une part à afficher correctement les chemins sous forme de liste et d'autre part à en retirer. Il me reste juste un bout de code à rajouter et ça devrait être terminé.
    Pour info, il n'y a rien de spécial à faire après avoir sous-classé, la mise à jour et la récupération des données se fait tout seul. Pour ceux qui veulent faire pareil, de la lecture:
    http://qt.developpez.com/doc/4.7/mod...w-programming/
    http://qt.developpez.com/doc/4.7/qde...onnees-c-2b-2b

    Cordialement

  17. #17
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Parfait.

    N'oublie pas de mettre le sujet en résolu.

    Bonne continuation.

  18. #18
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Juste une dernière question:
    Pour ma fonction setData, je voudrais lui donner en argument un index bien précis. Le dernier de la liste. Je ne peux pas lui donner uniquement un int. Je suis obligé de créer un index à partir de QML et lui donner en argument. Mais il ne reconnais pas le type, donc impossible de créer cet index manuellement. Comment est-ce que je peux faire?

    Voila où je bloque:
    Fonction C++
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool ListCheminModel::setData (const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.isValid() && role == Qt::EditRole) {
            stringList.replace(index.row(), value.toString());
            emit dataChanged(index, index);
            return true;
        }
        return false;
    }

    QML
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    FileDialog {
        id:fileDialog
        visible: true
        selectFolder:true
        title: "Choisissez un fichier"
        onAccepted{
            listeChemins.insertRows(listeChemins.rowCount(),1)
            listeChemins.setData(??????????,fileDialog.fileUrls,Qt.EditRole)  // Là je ne sais pas quoi lui donner comme argument pour l'index étant donné que je ne peux pas en créer depuis le QML
            pageLoader.source=""
        }
        onRejected{
            pageLoader.source=""
        } 
    }

  19. #19
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    Rien ne vous empêche de créer une nouvelle méthode prenant elle un int pour la ligne et l'exploiter à la place de setData() dans le QML.
    Dans l'exemple de l'article, il me semble qu'il y a une méthode similaire.

    Bonne soirée,
    Louis

  20. #20
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Merci comme ça, ça marche. Mais j'aurais bien aimé utiliser un QModelIndex. Là c'est dommage, je suis obligé de faire presque un copier/coller de la première fonction pour l'appeler une seule fois ( et du coup je n'utilise plus le setData utilisant un QModelIndex). Je reste insatisfaits de laisser du code qui ne sert à rien, même si ça marche.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/03/2011, 20h38
  2. Réponses: 8
    Dernier message: 26/03/2010, 08h16
  3. Une listView Verticale avec une image
    Par Finality dans le forum Windows Forms
    Réponses: 1
    Dernier message: 25/04/2009, 10h07
  4. Comment coder une requete dynamique avec une Variable binaire.
    Par BoromSikim dans le forum Développement
    Réponses: 11
    Dernier message: 03/03/2009, 17h17
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

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