Binding et affectation en QML

Il me semble que c’est une chose qui est déjà expliqué dans mon livre, mais une piqûre de rappel de fait jamais de mal.

En C++, l’écriture d’une propriété suit la forme classique suivante :

class MyObject : public QObject {
    Q_OBJECT
    Q_PROPERTY(int myProperty
               READ myProperty
               WRITE setMyProperty
               NOTIFY myPropertyChanged)
public: 
    int myProperty() const;
    void setMyProperty(int);
signals:
    void myPropertyChanged();
private:
    int m_myProperty {};
};

int MyObject::myProperty() const {
    return m_myProperty;
}

void MyObject::setMyProperty(int value) {
    if (value != m_myProperty) {
        m_myProperty = value;
        emit myPropertyChanged;
    }
}

Le code est volontairement détaillé pour montrer un point important : le signal myPropertyChanged est émis lorsque la valeur de m_myProperty est effectivement changée.

Dans la plupart des cas, il n’est pas nécessaire d’écrire explicitement ses fonctions, vous pouvez écrire :

class MyObject : public QObject {
    Q_OBJECT
    Q_PROPERTY(int myProperty
               MEMBER m_myProperty
               NOTIFY myPropertyChanged)
signals:
    void myPropertyChanged();
private:
    int m_myProperty {};
};

Ce signal est important, puisque que cela permet de creer un binding. Lorsque vous écrivez en QML :

Rectangle {
    width: anotherItem.width
    height: anotherItem.height / 2
}

Si la taille de anotherItem change, alors la taille du rectangle est automatiquement mise a jour. Les propriétés width et height sont mise a jour automatiquement lorsque les valeurs de anotherItem.width et anotherItem.height sont modifiées. En interne, les signaux anotherItem.widthChanged et anotherItem.heightChanged sont émis lorsque les valeurs changent, ces signaux sont récupérés par le binding et les valeurs de width et height sont mise a jour.

L’affectation permet de modifier la valeur d’une propriété en utilisant l’operateur = (comme en C++ et en JavaScript). Une différence importante avec le binding : la propriété ne sera pas mise a jour si la valeur change.

Rectangle {
    function updateSize() {
        width = anotherItem.width;
        height = anotherItem.height / 2;
    }
}

Dans ce cas, si la taille de anotherItem change, la taille du rectangle ne sera pas mise a jour automatiquement. Elle le sera uniquement en appelant manuellement la fonction updateSize.

Il est important de bien comprendre et differentier ces deux notions.

Il reste un dernier point a voir : comment créer un binding dans une fonction JavaScript ? La méthode la plus simple est d’utiliser la fonction Qt.binding :

Rectangle {
    function updateSize() {
        width = Qt.binding(function()
            { return anotherItem.width });
        height = Qt.binding(function()
            { return (anotherItem.height/2) });
    }
}

Avec cette syntaxe, les propriétés seront mises a jour automatiquement.

Documentation de Qt a consulter :

Publicités

Un commentaire sur « Binding et affectation en QML »

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s