Qt Reference Documentation

# Chapter 4: Using Custom Property Types

Files:

- declarative/tutorials/extending/chapter4-customPropertyTypes/app.qml
- declarative/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp
- declarative/tutorials/extending/chapter4-customPropertyTypes/piechart.h
- declarative/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp
- declarative/tutorials/extending/chapter4-customPropertyTypes/pieslice.h
- declarative/tutorials/extending/chapter4-customPropertyTypes/main.cpp
- declarative/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro

The `PieChart` type currently has a string-type property and a color-type property. It could have many other types of properties. For example, it could have an int-type property to store an identifier for each chart:

     // C++
     class PieChart : public QDeclarativeItem
     {
         Q_PROPERTY(int chartId READ chartId WRITE setChartId NOTIFY chartIdChanged)
         ...

     public:
         void setChartId(int chartId);
         int chartId() const;
         ...

     signals:
         void chartIdChanged();
     };

     // QML
     PieChart {
         ...
         chartId: 100
     }

We can also use various other property types. QML has built-in support for the types listed in the QML Basic Types documentation, which includes the following:

- bool, unsigned int, int, float, double, qreal
- QString, QUrl, QColor
- QDate, QTime, QDateTime
- QPoint, QPointF, QSize, QSizeF, QRect, QRectF
- QVariant

If we want to create a property whose type is not supported by QML by default, we need to register the type with QML.

For example, let's replace the use of the `property` with a type called "PieSlice" that has a `color` property. Instead of assigning a color, we assign an `PieSlice` value which itself contains a `color`:

     import Charts 1.0
     import QtQuick 1.0

     Item {
         width: 300; height: 200

         PieChart {
             id: chart
             anchors.centerIn: parent
             width: 100; height: 100

             pieSlice: PieSlice {
                 anchors.fill: parent
                 color: "red"
             }
         }

         Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color)
     }

Like `PieChart`, this new `PieSlice` type inherits from QDeclarativeItem and declares its properties with Q_PROPERTY():

     class PieSlice : public QDeclarativeItem
     {
         Q_OBJECT
         Q_PROPERTY(QColor color READ color WRITE setColor)

     public:
         PieSlice(QDeclarativeItem *parent = 0);

         QColor color() const;
         void setColor(const QColor &color);

         void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

     private:
         QColor m_color;
     };

To use it in `PieChart`, we modify the `color` property declaration and associated method signatures:

     class PieChart : public QDeclarativeItem
     {
         Q_OBJECT
         Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice)
         ...
     public:
         ...
         PieSlice *pieSlice() const;
         void setPieSlice(PieSlice *pieSlice);
         ...
     };

There is one thing to be aware of when implementing `setPieSlice()`. The `PieSlice` is a visual item, so it must be set as a child of the `PieChart` using QDeclarativeItem::setParentItem() so that the `PieChart` knows to paint this child item when its contents are drawn:

     void PieChart::setPieSlice(PieSlice *pieSlice)
     {
         m_pieSlice = pieSlice;
         pieSlice->setParentItem(this);
     }

Like the `PieChart` type, the `PieSlice` type has to be registered using qmlRegisterType() to be used from QML. As with `PieChart`, we'll add the type to the "Charts" module, version 1.0:

     int main(int argc, char *argv[])
     {
         ...
         qmlRegisterType<PieSlice>("Charts", 1, 0, "PieSlice");
         ...
     }

Try it out with the code in Qt's `examples/tutorials/extending/chapter4-customPropertyTypes` directory.