Qt 4.8: Chapter 3: Adding Property Bindings

Qt Reference Documentation

- Qt 4.8
- ALL VERSIONS

- A
- A
- A
- Print

# Chapter 3: Adding Property Bindings

Files:

- declarative/tutorials/extending/chapter3-bindings/app.qml
- declarative/tutorials/extending/chapter3-bindings/piechart.cpp
- declarative/tutorials/extending/chapter3-bindings/piechart.h
- declarative/tutorials/extending/chapter3-bindings/main.cpp
- declarative/tutorials/extending/chapter3-bindings/chapter3-bindings.pro

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.