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 :

Faisabilité : afficher un graphe depuis C++ avec QML


Sujet :

Qt Quick

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut Faisabilité : afficher un graphe depuis C++ avec QML
    Bonjour

    Je viens de commencer de travailler avec QML et je voudrais savoir si le cas suivant est faisable avec QML:

    Je veux faire afficher un graph depuis C++ avec QML dans la facon suivante:
    - chaque noeud est répresant par une image graphique - par exemple une icone grahique .png
    - on peut clicker (right mouse click) sur un noeud et pouvoir faire des actions simples sur le noeud (changer son nom, afficher/cacher son apparance)
    - les noeuds sont connectés avec des lignes graphique et le graph est affiché dans une facon simple à visualiser.


    J'ai vu qu'il existe GridView dans QML, mais je ne sais pas si je peux peindre des lignes graphique entre les elements. Et aussi, si je peux re-arranger les noeuds dans une facon simple à visualiser.

    Est-ce que vous pouvez me donner votre avis SVP si cela est faisable avec QML et si oui avec lequels elements QML on pourrait le realiser ?

    Merci beaucoup d'avance !

  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
    Bonsoir,

    C'est possible avec le module Qt Declarative de Qt (qui englobe QML) en réalisant du côté du C++ l'élément QML puis en l'exploitant du côté du QML. Pour les nœuds, il s'agirait d'un ListModel avec dedans les informations, affiché par un Repeater par-dessus l'élément QML du graphe. Je peux vous fournir un exemple si cette méthode vous intéresse.

    Pour la classe C++ du graphe elle-même, je vous propose d'étudier un code que j'avais donné précédemment :

    http://www.developpez.net/forums/d12...s/#post6744642

    Bonne continuation,
    Amnell.
    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

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Oui, je suis intéressé pour cette solution. J'aimerais avoir un exemple Stp.

    P.S. et surtout comment créer dynamiquement les objets QML Node a partir de C++ et les connecter avec des lignes ?

    Merci

  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
    Bonsoir,

    Rapidement :

    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
        Component.onCompleted{
            console.log("");
     
            nodeModel.append({"posX": 10, "posY": 5, "name": "Node 1", "opened": true});
            nodeModel.append({"posX": 2, "posY": 12, "name": "Node 2", "opened": false});
        }
     
        Graph {
            id: graph
            anchors.fill: parent
            // ...
     
            property int scaleX: 50
            property int scaleY: 50
     
            MouseArea {
                anchors.fill: parent
                onClicked{
                    nodeModel.append({"posX": mouseX / graph.scaleX, "posY": mouseY / graph.scaleY,
                                         "name": "Node " + (nodeModel.count + 1), "opened": true});
                }
            }
     
            Repeater {
                model: nodeModel
                delegate: Rectangle {
                    x: graph.scaleX * posX
                    y: graph.scaleY * posY
                    width: contentText.width + 10
                    height: opened ? 50 : 25
                    border.width: 1
                    border.color: "black"
     
                    Text {
                        id: contentText
                        visible: opened
                        text: name
                        anchors.centerIn: parent
                    }
     
                    MouseArea {
                        anchors.fill: parent
                        onClicked{
                            nodeModel.get(index).opened = !opened;
                        }
                    }
                }
            }
        }
     
        ListModel {
            id: nodeModel
        }
    Les propriétés scaleX et scaleY devront correspondre à l'échelle du graphe (en gros, 1 en abscisses équivaut à 50px, dans le cas présent). Cette propriété sera à définir dans la classe C++ du Graphe. Là, j'ai fait en sorte que lors qu'on clique sur une zone du graphe, ça ajoute un Node à la position du clic. De plus, le fait de cliquer sur un Node permet de l'ouvrir/le fermer, selon son état courant. Bref, voilà pour l'exemple.

    Par rapport à votre question : comment créer des éléments directement depuis le C++, l'idéal serait de passer par une contextProperty() :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MyNotifier
    {
        Q_OBJECT
    public:
        // ...
     
    signals:
        void createNodeRequest(int x, int y, const QString &name);
    };

    La définition de la propriété :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MyNotifier notifier;
    // ...
    viewer.rootContext()->setContextProperty("notifier", &notifier);

    Et dans le QML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        Connections {
            target: notifier
            onCreateNodeRequest{
                nodeModel.append({"posX": x, "posY": y, "name": name, "opened": true});
            }
        }
    Avec cette méthode, pour créer un Node depuis le C++, il suffit donc d'émettre le signal createNodeRequest() de l'instance "notifier".

    Il y a bien sûr d'autres solutions mais j'ai préféré vous présenter celle-ci.

    Bonne continuation,
    Amnell.
    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

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut fusion
    Merci beaucoup.

    Comment tu peindre des lignes qui connectent les noeud ?

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

    L'objectif est d'avoir ceci ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         ______
        | Node |
        |______|    /
           |   ____/
           |__/
          /
         /
    /\__/
    Dans ce cas, on connaît déjà le point de la courbe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x: graph.scaleX * posX
    y: graph.scaleY * posY
    D'où un petit exemple rapide qui reprend mon précédent code

    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
    Rectangle {
        id: graph
        width: 1024
        height: 800
     
        property int scaleX: 50
        property int scaleY: 50
     
        MouseArea {
            anchors.fill: parent
            onClicked{
                nodeModel.append({"posX": mouseX / graph.scaleX, "posY": mouseY / graph.scaleY,
                    "name": "Node " + (nodeModel.count + 1), "opened": true});
            }
        }
     
        Repeater {
            model: nodeModel
            delegate: Item {
                x: graph.scaleX * posX
                y: graph.scaleY * posY
                width: nodeArea.width
                height: nodeArea.height + 75
     
                Rectangle {
                    width: 1
                    height: 75
                    y: -75
                    color: "black"
                }
     
                Rectangle {
                    id: nodeArea
                    x: -Math.round(width / 2)
                    y: -75
                    width: contentText.width + 10
                    height: opened ? 50 : 25
                    border.width: 1
                    border.color: "black"
     
                    Text {
                        id: contentText
                        visible: opened
                        text: name
                        anchors.centerIn: parent
                    }
     
                    MouseArea {
                        anchors.fill: parent
                        onClicked{
                            nodeModel.get(index).opened = !opened;
                        }
                    }
                }
            }
        }
     
        ListModel {
            id: nodeModel
        }
    }
    Bonne continuation,
    Amnell.
    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

  7. #7
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Salut,

    Ton exemple est très bien, mais je ne comprends pas comment tu peux peindre une ligne qui connecte deux noeuds (dans ton cas le noeud est un rectangle avec un text) ?

    Merci

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

    Dans le cas présent, le nœud va être le rectangle avec une bordure qui contient un Text dedans. Pour la ligne, c'est le rectangle d'épaisseur 1px de couleur noire. Après, si on souhaite dessiner des lignes qui ne sont pas droites ou horizontales/verticales (ce qui pourrait être reproduit avec un Rectangle), soit on crée une classe côté C++ dont la fonction paint dessine une ligne bêtement avec un QPainter, soit on utilise http://qt.gitorious.org/qt-labs/qmlcanvas.

    Bonne continuation,
    Amnell.
    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

  9. #9
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    J'ai arrivé de créer des éléments Nodes dans un Repeater et les place comme je veux grâce aux paramètres posX et posY.

    Maintenant je veux peindre une ligne entre certains éléments.

    Du coup, j'ai implémenter la méthode paint() de la classe C++ Node:

    Code C++ : 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
    void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        QPen pen;
        pen.setColor(Qt::blue);
        pen.setStyle(Qt::SolidLine);
        pen.setWidth(2);
        painter->setPen(pen);
        painter->setRenderHints(QPainter::Antialiasing, true);
     
        for (QList<Node*>::const_iterator itParent = _parents.constBegin();
             itParent != _parents.constEnd();
             itParent++)
        {
            QPoint startPoint(this->posX(), this->posY());
            QPoint endPoint((*itParent)->posX(), (*itParent)->posY());
     
            painter->drawLine(startPoint, endPoint);
        }
    }

    Le probleme est que après dans mon main.cpp quand je crée 3 Nodes pour tester et j'ai fait la connexion entre deux (Node3.parent = Node2), je ne vois pas la ligne dessinée avec paint().

    Est-ce que tu sais comment ça marche avec la méthode paint(). Quand elle est appelée et comment on peut l'appeler exprès ? Ca marche avec un signal spécifique ?

    Merci d'avance

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

    Vous avez dû oublier ceci :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    setFlag(ItemHasNoContents, false);

    Attention cependant, la classe C++ "Node" est une toute autre chose que l'élément QML "Node".

    L'intérêt de QML reste d'avoir la logique du côté du code C++ et la partie graphique du côté du code QML. De ce fait, je vous proposerais plutôt de créer un élément "Link" qui permet de relier deux nœuds entre eux... et du côté du QML. La partie C++ permettra uniquement de coder le paint et d'ajouter quelques propriétés :

    Code C++ : 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
    #ifndef LINK_H
    #define LINK_H
     
    #include <QtGui>
    #include <QtDeclarative>
     
    class Link : public QDeclarativeItem
    {
        Q_OBJECT
        Q_PROPERTY(int fromX READ fromX WRITE setFromX NOTIFY fromXChanged)
        Q_PROPERTY(int fromY READ fromY WRITE setFromY NOTIFY fromYChanged)
        Q_PROPERTY(int toX READ toX WRITE setToX NOTIFY toXChanged)
        Q_PROPERTY(int toY READ toY WRITE setToY NOTIFY toYChanged)
     
    public:
        explicit Link(QDeclarativeItem* const parent = NULL)
            : QDeclarativeItem(parent), _fromX(0), _fromY(0), _toX(0), _toY(0)
        {
            // Notez la présence de cette ligne pour que paint() soit appelé :
            setFlag(ItemHasNoContents, false);
        }
     
    private slots:
        int fromX() const { return _fromX; }
        int fromY() const { return _fromY; }
        int toX() const { return _toX; }
        int toY() const { return _toY; }
        void setFromX(const int v) { _fromX = v; emit fromXChanged(); }
        void setFromY(const int v) { _fromY = v; emit fromYChanged(); }
        void setToX(const int v) { _toX = v; emit toXChanged(); }
        void setToY(const int v) { _toY = v; emit toYChanged(); }
     
    protected:
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
        {
            Q_UNUSED(option);
            Q_UNUSED(widget);
     
            QPen pen;
            pen.setColor(Qt::blue);
            pen.setStyle(Qt::SolidLine);
            pen.setWidth(2);
            painter->setPen(pen);
            painter->setRenderHints(QPainter::Antialiasing, true);
            painter->drawLine(QPoint(_fromX, _fromY), QPoint(_toX, _toY));
        }
     
    signals:
        void fromXChanged();
        void fromYChanged();
        void toXChanged();
        void toYChanged();
     
    private:
        int _fromX;
        int _fromY;
        int _toX;
        int _toY;
    };
     
    #endif // LINK_H

    À ajouter dans le main.cpp :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    qmlRegisterType<Link>("MyLib", 1, 0, "Link");

    Et du coup, l'exemple QML donné plutôt avec en plus des ajouts commentés :

    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
    import QtQuick 1.1
    import MyLib 1.0
     
    Rectangle {
        id: graph
        width: 1024
        height: 800
     
        property int scaleX: 50
        property int scaleY: 50
     
        // Ajout d'une propriété selectedItem pour relier l'élément
        // à un autre élément avec un Link : on a besoin de savoir quel
        // est l'index dans le modèle de l'item sélectionné.
        property int selectedItem: -1;
     
        MouseArea {
            anchors.fill: parent
            onClicked{
                if (graph.selectedItem != -1)
                {
                    // Il y a un item sélectionné et on a cliqué ailleurs.
                    // On retire la sélection :
                    graph.selectedItem = -1;
                }
                else
                {
                    // Vu qu'il n'y a pas d'item sélectionné,
                    // on peut ajouter un Node au graph :
                    nodeModel.append({"posX": mouseX / graph.scaleX,
                        "posY": mouseY / graph.scaleY,
                        "name": "Node " + (nodeModel.count + 1)});
                }
            }
        }
     
        // Le Repeater qui va afficher tous les liens entre les Nodes :
        Repeater {
            model: linkModel
            // Le delegate sera notre item "Link", défini du coté du C++
            delegate: Link {
                fromX: nodeModel.get(nodeFrom).posX * graph.scaleX
                fromY: nodeModel.get(nodeFrom).posY * graph.scaleY
                toX: nodeModel.get(nodeTo).posX * graph.scaleX
                toY: nodeModel.get(nodeTo).posY * graph.scaleY
                anchors.fill: parent
            }
        }
     
        Repeater {
            model: nodeModel
            delegate: Item {
                x: graph.scaleX * posX
                y: graph.scaleY * posY
                width: nodeArea.width
                height: nodeArea.height + 75
     
                Rectangle {
                    width: 1
                    height: 75
                    y: -75
                    color: "black"
                }
     
                Rectangle {
                    id: nodeArea
                    x: -Math.round(width / 2)
                    y: -75
                    width: contentText.width + 10
                    height: 50
     
                    // La couleur change selon le fait que le noeud soit sélectionné ou non :
                    color: index == graph.selectedItem ? "lightgrey" : "white"
     
                    border.width: 1
                    border.color: "black"
     
                    Text {
                        id: contentText
                        anchors.centerIn: parent
                        text: name
                    }
     
                    MouseArea {
                        anchors.fill: parent
                        onClicked{
                            if (graph.selectedItem == -1)
                            {
                                // Lors d'un clic sur le Node, on change l'élément
                                // actuellement sélectionné s'il n'y a pas de sélection :
                                graph.selectedItem = index;
                            }
                            else
                            {
                                // Sinon, on ajoute un lien entre ce Node et le Node sélectionné :
                                linkModel.append({"nodeFrom": graph.selectedItem, "nodeTo": index});
                                // On efface alors la sélection :
                                graph.selectedItem = -1;
                            }
                        }
                    }
                }
            }
        }
     
        ListModel {
            id: nodeModel
        }
     
        // Ajout d'un modèle pour les
        // liens entre les Nodes :
        ListModel {
            id: linkModel
        }
    }
    Je n'ai pas trop le temps d'expliquer plus en détail tout ça ce soir, donc si vous avez des questions, n'hésitez pas à les poser, j'y répondrai demain.

    Bonne soirée,
    Amnell.
    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

  11. #11
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Pour l'instant je vais laisser la création des liens (lignes) dans la méthode paint() de Node.cpp

    J'ai bien mis dans le constructeur de Node.

    Mais je ne vois pas des lignes dessinées.

    J'ai tracé le code, je passe bien par la méthode paint(), mais par contre je passe plusieurs fois, pas seulement 3 fois (j'ai trois objets Node).
    Et chaque fois le pointer this pointe vers un objet vide de type Node et pas vers le vrai object Node, que j'ai créé avant.

    Je ne comprends pas pourquoi on appelle paint avec un this qui pointe vers un objet vide.

    Tu as une idée ?

    Merci d'avance

  12. #12
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    J'ai trouvé le probleme.

    En fait, QML appelle paint() sur une instance de Node.cpp, qui est vide.
    Apres QML copie les properties de C++ qui sont declaré comme roles ou Q_Properties.

    Donc, j'ai crée une role en plus -> parentNodes /QList<Node*> dans le Node.cpp/ qui contient tous les parents d-un node.

    Donc, je veux desinner une ligne pour chaque membre dans parentNodes dans la fonctionne onCompleted, alors il faut faire dans Node.qml

    Component.onCompleted: { for each in parentNodes, draw line posX, posY to iteratorEachInParentNodes.posX, posY}

    Mais je ne connais pas le syntax.

    Tu peux m'aider un peu stp ?

    Merci d-avance

    [edit]

    Peut etre qqchose comme:

    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
     
    Node {
        id: nodeDelegate
        x: posX
        y: posY
        visible: isDisplayed
     
        Image{
            id : nodeIcon
            source: iconFilePath
        }
     
        Text {
           anchors.top: nodeIcon.bottom
           text: nodeID
        }
     
        MouseArea {
           anchors.fill: parent
        }
     
        Component.onCompleted{
            for (var i=0; i < parentNodes.count(); i++)
            {
                Path {
                    startX: posX; startY: posY
                    PathLine{x: parentNodes[i].posX ; y: parentNodes[i].posY}
                }
            }
        }
    }


    Mais cela ne se compile pas. Je ne connais pas le syntax exact ...

    Tu as une idée ?

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

    Le fait que la méthode paint() soit appelée plusieurs fois signifie qu'il y a eu plusieurs demandes de peinture (du genre, un élément situé au-dessus a demandé à être repeint, ce qui a engendré une repeinture de l'élément, ou bien vous avez masqué la fenêtre et l'avez réaffiché, etc.). D'ailleurs, je m'aperçois que j'ai oublié de rajouter les demandes de repeinture dans les fonction set[...]X/Y() de la classe de l'exemple que j'ai donné dans mon précédent post.

    La fonction onCompleted est appelée une seule fois, au moment où l'élément a fini d'être chargé. De ce fait, ce n'est pas nécessairement ce handler qui vous intéresse.

    Pourrais-je voir le code source de l'élément Node (celui qui a dû recevoir un qmlRegisterType et qui contient la méthode paint() - à moins que ce ne soit Node.qml qui crée l'élément, auquel cas j'aimerais voir la classe avec le paint()) ?

    Bonne continuation,
    Amnell.
    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

  14. #14
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Salut,

    Voici le code source:

    main.qml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    import QtQuick 1.0
     
    Rectangle {
        width:  500
        height: 500
     
        Repeater {
            anchors.fill: parent
            model: configModel
            delegate: Node{}
        }
    }

    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
     
    import QtQuick 1.0
    import NodeLib 1.0
     
    Node {
        id: nodeDelegate
        x: posX
        y: posY
        visible: isDisplayed
     
        Image{
            id : nodeIcon
            source: iconFilePath
        }
     
        Text {
           anchors.top: nodeIcon.bottom
           text: nodeID
        }
     
        MouseArea {
           anchors.fill: parent
        }
    // code pour onCOmpleted in pseudocode. Syntax pas sur !!!
        Component.onCompleted{
            for (var i=0; i < parentNodes.count; i++)
            {
                Path: [
                   // startX: posX,
                   // startY: posY,
                    PathLine {
                        x: parentNodes.get(i).posX
                        y: parentNodes[i].posY
                    }
                ]
            }
        }
    }
    main.cpp
    Code C++ : 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
     
    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
        QScopedPointer<QApplication> app(createApplication(argc, argv));
     
        QDeclarativeView    declarativeView;
        qmlRegisterType<Node>("NodeLib", 1, 0, "Node");
     
        ConfigurationModel* p_configModel = ConfigurationModel::GetConfigModelInstance();
     
        //p_configModel->addNodeInConfigurationModel(new Node("PanelXXXX", PLUG_IN, EVALUATION_BLOCK, "./ui-images/cutetube.png"));
     
        //Node *p_nodeY = new Node("PanelYYYY", PLUG_IN, EVALUATION_BLOCK, "./ui-images/cutetube.png");
        Node *p_nodeY = new Node();
        p_nodeY->setNodeID("PanelYYYY");
        p_nodeY->setIconFilePath("./ui-images/cutetube.png");
        p_configModel->addNodeInConfigurationModel(p_nodeY);
     
        // Node *p_nodeZ = new Node("PanelZZZZ", PLUG_IN, EVALUATION_BLOCK, "./ui-images/cutetube.png");
        Node *p_nodeZ = new Node();
        p_nodeZ->setNodeID("NODE ZZZZ");
        p_nodeZ->setIconFilePath("./ui-images/cutetube.png");
     
     
        p_nodeY->setPosX(100);
        p_nodeY->setPosY(100);
        p_nodeY->setIsDisplayed(true);
     
        p_nodeZ->setPosX(200);
        p_nodeZ->setPosY(200);
     
        p_nodeZ->connectTo(p_nodeY);
     
        p_configModel->addNodeInConfigurationModel(p_nodeZ);
     
        // if the configuration has been changed, you need to call setContextProperty() again to update the QML view
     
        declarativeView.rootContext()->setContextProperty("configModel", p_configModel);
     
        declarativeView.setSource(QUrl::fromLocalFile("qml/ConfigurationView/main.qml"));
        declarativeView.show();
     
        return app->exec();
    }


    Node.h
    Code C++ : 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
     
    #ifndef NODE_H
    #define NODE_H
     
    #include <QString>
    #include <QList>
    #include <QDeclarativeItem>
     
    #include <QPainter>
    #include <QPen>
    #include <QPoint>
    #include <QStyleOptionGraphicsItem>
     
    #include "GlobalDeclarations.h"
     
    // Inherit from QDeclarativeItem in order to override paint() method and to display links to parent nodes
    class Node : public QDeclarativeItem
    {
        Q_OBJECT
        // Q_PROPERTY(QString iconFilePath  READ getIconFilePath WRITE setIconFilePath NOTIFY iconFilePathChanged)
        // Q_PROPERTY(QString nodeID  READ getNodeID WRITE setNodeID NOTIFY nodeIDchanged)
     
     
    public:
        // Constructors
        Node();
        Node(QString nodeID, NodeType nodeType, PlugInType plugInType, QString iconFilePath);
     
        // Destructor
        ~Node();
     
        QString nodeID() const;
        Q_INVOKABLE bool setNodeID(const QString &nodeID);
     
        QString  iconFilePath() const;
        Q_INVOKABLE bool setIconFilePath(const QString &iconFilePath);
     
        Q_INVOKABLE int posX() const;
        Q_INVOKABLE bool setPosX(int posX);
     
        Q_INVOKABLE int posY() const;
        Q_INVOKABLE bool setPosY(int posY);
     
        bool isDisplayed() const;
        Q_INVOKABLE bool setIsDisplayed(bool value);
     
        const QList<Node*>& parentNodes() const;
        QList<Node*>& accessParents();
        Q_INVOKABLE bool addParent(Node* p_parentNode);
     
        void hide();
        void show();
     
        void connectTo(Node* p_toNode);
        void disconnectFrom(Node* p_toNode);
        void removeNode();
     
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
       // Q_INVOKABLE void update();
     
     
    signals:
        void nodeIDchanged(QString data);
        void iconFilePathChanged(QString data);
        void posXChanged(int data);
        void posYChanged(int data);
        void isDisplayedChanged(bool data);
        void parentNodesChanged(QList<Node*>& data);
        void dataChanged();
     
     
    protected:
     
        void addChild(Node* p_childNode);
        const QList<Node*>& getChildren() const;
        QList<Node*>& accessChildren();
     
     
     
    private:
        QString         _nodeID;
        NodeType        _nodeType;
        PlugInType      _plugInType;
        QString         _iconFilePath;
        int             _posX;
        int             _posY;
        bool            _isDisplayed;
     
        QList<Node*>    _parents;
        QList<Node*>    _children;
    };
     
    #endif // NODE_H

    Code C++ : 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
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    #include <Node.h>
     
     
    // Constructors
    Node::Node() : _nodeID(""), _nodeType(NOT_DEFINED), _plugInType(NOT_DEFINEDD), _iconFilePath(""), _posX(0), _posY(0), _isDisplayed(true)
    {
        setFlag(ItemHasNoContents, false);
        update();
    }
     
     
     
    Node::Node(QString nodeID, NodeType nodeType, PlugInType plugInType, QString iconFilePath) :
        QDeclarativeItem (), _nodeID(nodeID), _nodeType(nodeType), _plugInType(plugInType), _iconFilePath(iconFilePath), _posX(1), _posY(1), _isDisplayed(true)
    {
        emit nodeIDchanged(_nodeID);
        emit iconFilePathChanged(_iconFilePath);
        emit posXChanged(_posX);
        emit posYChanged(_posY);
        emit isDisplayedChanged(_isDisplayed);
        emit dataChanged();
     
        setFlag(ItemHasNoContents, false);
    }
     
     
    /*
    // copy constructor
    Node::Node(Node &sourceNode)
    {
        this->_nodeID       = sourceNode.nodeID();
        this->_iconFilePath = sourceNode.iconFilePath();
        this->_parents      = sourceNode.accessParents();
     
        this->update();
    }
    */
     
     
    // Destructor
    Node::~Node()
    {
    }
     
     
     
    QString Node::nodeID() const
    {
        return _nodeID;
    }
     
     
    bool Node::setNodeID(const QString &nodeID)
    {
        _nodeID = nodeID;
        emit nodeIDchanged(_nodeID);
        emit dataChanged();
     
        return true;
    }
     
     
    QString  Node::iconFilePath() const
    {
        return _iconFilePath;
    }
     
     
    bool Node::setIconFilePath(const QString &iconFilePath)
    {
        _iconFilePath = iconFilePath;
        emit iconFilePathChanged(_iconFilePath);
        emit dataChanged();
     
        return true;
    }
     
     
    int Node::posX() const
    {
        return _posX;
    }
     
     
    bool Node::setPosX(int posX)
    {
        _posX = posX;
        emit posXChanged(_posX);
        emit dataChanged();
     
        return true;
    }
     
     
    int Node::posY() const
    {
        return _posY;
    }
     
     
    bool Node::setPosY(int posY)
    {
        _posY = posY;
        emit posYChanged(_posY);
        emit dataChanged();
     
        return true;
    }
     
     
    bool Node::isDisplayed() const
    {
        return _isDisplayed;
    }
     
     
    bool Node::setIsDisplayed(bool value)
    {
        _isDisplayed = value;
        emit isDisplayedChanged(_isDisplayed);
        emit dataChanged();
     
        return true;
    }
     
     
    void Node::hide()
    {
        this->setIsDisplayed(false);
    }
     
     
    void Node::show()
    {
        this->setIsDisplayed(true);
    }
     
     
    void Node::connectTo(Node* p_toNode)
    {
        this->_parents.append(p_toNode);
     
        //update();
    }
     
     
    void Node::disconnectFrom(Node* p_toNode)
    {
    }
     
     
    void Node::removeNode()
    {
    }
     
     
    const QList<Node*>& Node::parentNodes() const
    {
        return _parents;
    }
     
     
    QList<Node*>& Node::accessParents()
    {
        return _parents;
    }
     
     
    bool Node::addParent(Node* p_parentNode)
    {
        this->_parents.append(p_parentNode);
     
        emit parentNodesChanged(_parents);
        emit dataChanged();
     
        return true;
    }
     
     
     
    void Node::addChild(Node* p_childNode)
    {
        _children.append(p_childNode);
    }
     
     
    const QList<Node*>& Node::getChildren() const
    {
        return _children;
    }
     
     
    QList<Node*>& Node::accessChildren()
    {
        return _children;
    }
     
     
    void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option)
        Q_UNUSED(widget)
     
        QPen pen;
        pen.setColor(Qt::blue);
        pen.setStyle(Qt::SolidLine);
        pen.setWidth(6);
        painter->setPen(pen);
        painter->setRenderHints(QPainter::Antialiasing, true);
     
        /*
        QPoint startPoint(this->posX(), this->posY());
        QPoint endPoint(-50, -50);
     
        painter->drawLine(startPoint, endPoint);
        */
     
        for (QList<Node*>::const_iterator itParent = this->_parents.begin();
             itParent != this->_parents.end();
             ++itParent)
        {
            int debug = this->posX();
                   debug = this->posY();
                   debug = (*itParent)->posX();
                   debug = (*itParent)->posY();
            QPoint startPoint(this->posX(), this->posY());
            QPoint endPoint((*itParent)->posX(), (*itParent)->posY());
     
            painter->drawLine(startPoint, endPoint);
        }
    }
     
    /*
    void Node::update()
    {
        // QDeclarativeItem::update();
        QPainter* p_painter = new QPainter();
        QStyleOptionGraphicsItem* p_option = new QStyleOptionGraphicsItem();
        paint(p_painter, p_option);
     
        //delete p_painter;
        //delete p_option;
    }
    */


    Je suis blocké et je ne peux avancer a cause de ce problème avec dessin de lignes entre les noeuds.

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

    Dans votre classe Node, plutôt que de passer par des fonction Q_INVOKABLE, vous devriez passer par des propriétés, ce qui vous permettrait d'opérer dynamiquement plutôt que d'avoir à appeler vous-même les fonctions lors de changements.

    Là, l'intérêt semble de relier les Nodes entre eux. En admettant que les méthodes connectTo() et disconnectTo() - en ajoutant update() pour avoir droit à un appel à paint() - prenant en paramètre un Node* soient Q_INVOKABLE, on pourrait envisage un Component.onCompleted du main.qml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Repeater {
        anchors.fill: parent
        model: configModel
        delegate: Node{}
    }
     
    Component.onCompleted{
        for (var i = 0; i < configModel.count - 1; ++i)
            configModel.get(i).connectTo(configModel.get(i + 1));
    }
    Vous pouvez également ajouter des MouseArea pour faire comme dans mon exemple (relier les éléments en cliquant) et faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    configModel.get(selectedNode).connectTo(configModel.get(index));
    Dans le onClicked de la MouseArea du Node.

    Bonne continuation,
    Amnell.
    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

  16. #16
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    C-est bien cette proposition.

    Par contre dans ton exemple, tu fais connection entre le node courrant et tous ces précedant noeud.

    Moi, je veux qu'il y a la possibilité de faire connection entre le noeud courrant et certains des noeuds (qui sont marqués dans sa liste _parents).

    Ca je ne sais pas comment faire, sinon exemple est bon.

    Merci beaucoup

  17. #17
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    J'ai essayé de faire main.qml comme tu as proposé:

    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
     
    Rectangle {
        width:  500
        height: 500
     
        Repeater {
            anchors.fill: parent
            model: configModel
            delegate: Node {}
        }
     
        Component.onCompleted{
            for (var i = 0; i < configModel.count - 1; ++i)
                configModel.get(i).connectTo(configModel.get(i + 1));
        }
    }
    Après , j'ai tracé le code, mais on ne rentre pas dans le for loop !
    Ca veut dire, que configModel.count est 0 au moment d'appeler onCompleted. C'est bizarre quand meme ...

    Sinon, je trouve l'idée comme bonne.

    Juste comme j'ai ecrit dans mon message précédant, je veux connecter dynamiquement un noeud donné à un certain nombre de noeud spécifiés

    Par exemple, une configuration de 3 noeud:
    - noeud 1 - non connecté
    - noeud 2 - non connecté
    - noeud 3 - connecté à noeud 1

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

    Le problème vient probablement du fait que le modèle soit vide ou bien que sa fonction count() retourne 0, n'ayant pas été réimplémentée dans le C++. Par contre, je vous conseillerais plus de gérer vos Nodes du côté du QML, cela éviterait de mélanger le model et la view comme cela.

    Bonne continuation,
    Amnell.
    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

  19. #19
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 13
    Points : 2
    Points
    2
    Par défaut
    Oui, mon idée était de faire le dessin des connections par la fonction paint(), mais le probleme est que cette fonction est appellé dans QML a partir d'une instance vide de la classe Node.

    QML crée des instances de Node a partir de Node() et ils sont vides. Apres plus tard QML copie des properties (roles) a partir du model.

    Donc, quand paint() est appellé, la liste _parents est vide et je ne peux pas dessiner les liens.

    Tu as une idée ?

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

    L'idéal serait d'avoir un modèle contenant les informations - non les Nodes eux-mêmes - permettant de créer les Nodes et de les relier ultérieurement entre eux par la suite.

    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
    ListModel {
        id: nodeModel
    }
     
    // Les Nodes sont créés ici, pas dans le C++ :
    Repeater {
        model: nodeModel
        delegate: Node {
            nodeName: name
            nodeType: type
            // ...
        }
    }
     
    Component.onCompleted{
        // On crée quelques Nodes en modifiant le nodeModel :
        nodeModel.append({"name": "Node 1", "type": 0, /*...*/});
        nodeModel.append({"name": "Node 2", "type": 4, /*...*/});
     
        // On relie tout le monde :
        for (var i = 0; i < configModel.count - 1; ++i)
            configModel.get(i).connectTo(configModel.get(i + 1));
    }
    Pour cela, vous devrez ajouter les Q_PROPERTY dans votre classe Node.

    Bonne continuation,
    Amnell.
    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

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

Discussions similaires

  1. [MySQL] afficher un graphe avec jpgraph
    Par yotman dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 12/07/2013, 16h07
  2. afficher deux graphes avec deux boutons
    Par biliesod dans le forum Interfaces Graphiques
    Réponses: 1
    Dernier message: 18/06/2011, 19h08
  3. Réponses: 0
    Dernier message: 09/06/2010, 10h08
  4. Afficher un graphe avec les mfc?
    Par eldana dans le forum MFC
    Réponses: 4
    Dernier message: 12/06/2008, 12h46
  5. Réponses: 1
    Dernier message: 28/03/2008, 16h23

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