MeeGo 1.2 Harmattan Developer Documentation Develop for the Nokia N9

Chapter 3: Adding Property Bindings

Files:

Property bindings is a powerful feature of QML that allows values of different elements to be synchronized automatically. It uses signals to notify and update other elements' values when property values are changed.

Let's enable property bindings for the color property. That means if we have code like this:

 import Charts 1.0
 import QtQuick 1.0

 Item {
     width: 300; height: 200

     Row {
         anchors.centerIn: parent
         spacing: 20

         PieChart {
             id: chartA
             width: 100; height: 100
             color: "red"
         }

         PieChart {
             id: chartB
             width: 100; height: 100
             color: chartA.color
         }
     }

     MouseArea {
         anchors.fill: parent
         onClicked: { chartA.color = "blue" }
     }

     Text {
         anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
         text: "Click anywhere to change the chart color"
     }
 }

The "color: chartA.color" statement binds the color value of chartB to the color of chartA. Whenever chartA's color value changes, chartB's color value updates to the same value. When the window is clicked, the onClicked handler in the MouseArea changes the color of chartA, thereby changing both charts to the color blue.

It's easy to enable property binding for the color property. We add a NOTIFY feature to its Q_PROPERTY() declaration to indicate that a "colorChanged" signal is emitted whenever the value changes.

 class PieChart : public QDeclarativeItem
 {
     ...
     Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
 public:
     ...
 signals:
     void colorChanged();
     ...
 };

Then, we emit this signal in setPieSlice():

 void PieChart::setColor(const QColor &color)
 {
     if (color != m_color) {
         m_color = color;
         update();   // repaint with the new color
         emit colorChanged();
     }
 }

It's important for setColor() to check that the color value has actually changed before emitting colorChanged(). This ensures the signal is not emitted unnecessarily and also prevents loops when other elements respond to the value change.

The use of bindings is essential to QML. You should always add NOTIFY signals for properties if they are able to be implemented, so that your properties can be used in bindings. Properties that cannot be bound cannot be automatically updated and cannot be used as flexibly in QML. Also, since bindings are invoked so often and relied upon in QML usage, users of your custom QML types may see unexpected behavior if bindings are not implemented.