qml中自定义属性类型

如果我们想使用一个QML并不支持的类型,那么我们就需要向QML注册这个类型。 比如,我们现在使用一个新的名为pieSlice的属性替换掉之前使用的color属性,这个新的pieSlice属性的类型是"PieSlice",一种QML内置并不支持的类型。 于是我们就可以在QML中这样使用:

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

下面我们来看一下如何实现pieSlice这个属性:

class PieChart : public QDeclarativeItem
 {
   Q_OBJECT
   Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice)
   ...
 public:
   ...
   PieSlice *pieSlice() const;
   void setPieSlice(PieSlice *pieSlice);
   ...
 };
PieSlice *PieChart::pieSlice() const
{
   return m_pieSlice;
}
void PieChart::setPieSlice(PieSlice *pieSlice)
 {
   m_pieSlice = pieSlice;
   pieSlice->setParentItem(this);
 }

这里要注意的是,由于PieSlice是一个可见的Item,因此我们需要使用QDeclarativeItem::setParentItem(),把它注册成PieChart的孩子。于是当PieChart的内容需要绘制的时候,PieChart就会Paint它的这个孩子。我们现在再来看一下PieSlice具体是如何实现的:

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 一样,这个新的PieSlice类型也只从QDeclarativeItem继承下来的,并且使用Q_PROPERTY()来声明它的属性。最后,我们需要使用qmlRegisterType() 把PieSlice 注册为QML可用的类型。由于 PieSlice 是和 PieChart 在一起的,因此我们把 PieSlice 也注册到 版本号为 1.0 的"Charts" 模块。

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