第 4 章:使用自定义特性类型

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 基本类型 documentation, which includes the following:

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)
}
					

PieChart ,此新 PieSlice 类型继承自 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;
};
					

要使用它在 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() PieSlice is a visual item, so it must be set as a child of the PieChart 使用 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);
}
					

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 目录。

文件: