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 :

Envoyer un objet QList<Object> au code QML


Sujet :

Qt Quick

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 38
    Points : 26
    Points
    26
    Par défaut Envoyer un objet QList<Object> au code QML
    Bonjour,

    J'aurais une petite question, je réalise actuellement une petite application avec QtQuiCK QML, je débute. J'ai fait une classe storage qui me permet depuis QML d'effectuer des opérations sur une base de données SQL. Jusque là aucun soucis tout fonctionne. Dans ma classe storage j'ai une fonction setQuery que voici :
    Code qt : 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
    QList<Note> Storage::setQuery(QString query)
    {
        QList<Note> noteItems;
        QSqlQuery qsqlQuery;
        bool ok = qsqlQuery.exec(query);
        if(!ok)
        {
            qDebug() << "Résultat erreur setQuery" << m_sqlDatabase.lastError();
        }
        else
        {
     
            while (qsqlQuery.next()) {
                Note my_note;
                QString note = qsqlQuery.value("message").toString();
                my_note.setMessage(note);
     
                noteItems.append(my_note);
            }
        }
     
        return noteItems;
    }

    Je retourne ici en fonction des résultats une QList d'objet Note, aucun problème tout fonctionne du coté C++. Le problème c'est que j'appelle cette fonction depuis QML en Javascript et au retour j'ai cette erreur :
    Error: Unknown method return type: QList<Note>

    Je ne comprends pas trop pourquoi

    Sinon qu'elle serait les autres moyen disponibles pour retourner les résultats de ma requête SQL vers QML ?

  2. #2
    Membre averti
    Avatar de DaveShot
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 238
    Points : 384
    Points
    384
    Par défaut
    Bonjour,

    la méthode setQuery est-elle invokable (Q_INVOKABLE)?

    Cordialement,
    - N'hésitez pas à consulter les liens vers les FAQs, les cours et tutoriels -

    Daveshot

  3. #3
    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,

    En général, pour retourner quelque chose au QML sans risque, c'est assez pratique de retourner le tout sous forme de QVariant/QVariantList, ce qui garantie que le type retourné est valide. De là, le QML saura bien qu'il a affaire à une liste. Par contre, pour l'objet lui-même, il ne connaitra pas, donc il vous sera nécessaire d'appeler qmlRegisterType<Note> ou qmlRegisterUncreatableType<Note> avec les paramètres associés pour que l'élément soit connu du QML.

    Bonne journée,
    Louis
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 38
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par DaveShot Voir le message
    Bonjour,

    la méthode setQuery est-elle invokable (Q_INVOKABLE)?

    Cordialement,
    Oui oui elle est Q_INVOKABLE

    Citation Envoyé par Amnell Voir le message
    Bonjour,

    En général, pour retourner quelque chose au QML sans risque, c'est assez pratique de retourner le tout sous forme de QVariant/QVariantList, ce qui garantie que le type retourné est valide. De là, le QML saura bien qu'il a affaire à une liste. Par contre, pour l'objet lui-même, il ne connaitra pas, donc il vous sera nécessaire d'appeler qmlRegisterType<Note> ou qmlRegisterUncreatableType<Note> avec les paramètres associés pour que l'élément soit connu du QML.

    Bonne journée,
    Louis
    Ok je vais essayer de faire ça, je vais me renseigner, je débute vraiment en QML, je déclare un QVariantList comme une QList, du genre QVariantList<Note> et j'effectue ensuite un append pour ajouter mes objets?

  5. #5
    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,

    De mémoire, ceci devrait fonctionner.

    Dans le .qml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import Example 1.0
     
    // ...
     
    function myFunc()
    {
        var nodes = myClass.getNodes();
        for (var i = 0; i < nodes.length; ++i)
            doSomething(nodes[i]);
    }
    Côté C++ :

    Code qt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    QVariantList MyClass::getNodes()
    {
        QVariantList list;
        for (int i = 0; i < 10; ++i)
            list.append(new Node(i));
        return list;
    }

    main.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qmlRegisterUncreatableType<Node>("Example", 1, 0, "Node", "Core class");
    Vous pouvez également fonctionner non pas par allocation dynamique mais par copie, mais dans ce cas il vous faudra utiliser la ligne suivante à la place du qmlRegister :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qRegisterMetaType<Node>("Node");
    Dans le cas que je vous ai montré, attention à la libération de la mémoire et attention aussi à bien hériter de QObject. Vous pourrez alors manipuler l'objet par le biais de ses propriétés.

    Bonne journée,
    Louis
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 38
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Amnell Voir le message
    De mémoire, ceci devrait fonctionner.
    Merci de ta réponse, mais je me pose une question, si je fait comme tu me dit dans le c++, au moment ou je vais faire list.append(new Node(i)); ou new Node est un objet d'une classe perso, je ne vais pas avoir une erreur au moment de la compilation ?

    Et pourquoi new Node(i) et pas une new MyClass ?

  7. #7
    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,

    QVariant vous permet de placer dedans à peu près n'importe quoi, et vous pouvez l'étendre via diverses macros si nécessaires. Cependant, la difficulté est de pouvoir exploiter le type stocké avec QML.
    Je vous ai fait un exemple rapide pour illustrer :

    Code qt : 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
    class Human : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
     
    public:
        Human()
        {
        }
     
        Human(const QString &name)
            : _name(name)
        {
        }
     
        const QString &name() const { return _name; }
        void setName(const QString &n) { _name = n; emit nameChanged(); }
     
    signals:
        void nameChanged();
     
    private:
        QString _name;
    };
     
    class Room : public QObject
    {
        Q_OBJECT
     
    public:
        Room()
        {
            for (int i = 0; i < 10; ++i)
                _people.append(new Human(QString("Human %1").arg(i)));
        }
     
    public slots:
        QVariantList getPeople() const
        {
            QVariantList list;
     
            foreach (Human *human, _people)
                list.append(QVariant::fromValue(human));
     
            return list;
        }
     
    private:
        QList<Human *> _people;
    };
     
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
     
        qmlRegisterType<Human>("Room", 1, 0, "Human");
     
        Room room;
     
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("room", &room);
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
     
        return app.exec();
    }
     
    #include "main.moc"

    Dans le main.qml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Component.onCompleted{
        var people = room.getPeople();
        for (var i = 0; i < people.length; ++i)
            console.log("> " + people[i].name);
    }
    Le résultat est le suivant :

    qml: > Human 0
    qml: > Human 1
    qml: > Human 2
    qml: > Human 3
    qml: > Human 4
    qml: > Human 5
    qml: > Human 6
    qml: > Human 7
    qml: > Human 8
    qml: > Human 9
    Après, dans le cas présent, ce n'est pas forcément optimal de faire de la conversion QList<Human*> vers QVariantList et de dupliquer la liste pour y stocker chaque Human*. Pour palier à cela, il y a pas mal de solutions, comme l'utilisation de QQmlListProperty ou bien tout simplement la définition d'un type custom de QAbstractListModel. Tout dépend de vos besoins, après.

    Bonne soirée,
    Louis
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

Discussions similaires

  1. Accéder à l'objet 'session' dans le code du controleur
    Par chat_roux dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 03/12/2007, 20h37
  2. [DEV] Protéger les données des objets en objective-C
    Par Ceylo dans le forum Objective-C
    Réponses: 0
    Dernier message: 01/12/2007, 16h11
  3. Réponses: 2
    Dernier message: 19/09/2007, 10h21
  4. Envoyer l'objet AD séléctionné en paramètre d'un script
    Par diableOcorps dans le forum VBScript
    Réponses: 0
    Dernier message: 26/07/2007, 17h42
  5. [Réseau]Envoyer un Objet sur le réseau
    Par Battosaiii dans le forum Entrée/Sortie
    Réponses: 14
    Dernier message: 18/12/2005, 15h34

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