天天看點

Qt5官方demo解析集19——Chapter 5: Using List Property Types

本系列所有文章可以在這裡檢視http://blog.csdn.net/cloud_castle/article/category/2123873

接上文Qt5官方demo解析集18——Chapter 4: Using Custom Property Types

上個例子向我們展示了如何為QML調用的C++類型添加自定義類型的屬性,在這個例子中我們更進一步,将這個類型更換為一個PieSlice的清單,以此得到更豐富的處理能力。

項目檔案與上個例子是一樣的。

還是先看看piechart.h:

#ifndef PIECHART_H
#define PIECHART_H

#include <QtQuick/QQuickItem>

class PieSlice;                    // 由于這裡隻使用了PieSlice的指針,我們可以使用前向聲明

//![0]
class PieChart : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<PieSlice> slices READ slices)  // 我們使用QQmlListProperty<PieSlice>來定義slices屬性的類型
//![0]                                                         // 該屬性是一個PieSlice的清單,而QQmlListProperty則為我們提供了在QML中擴充該清單成員的能力
    Q_PROPERTY(QString name READ name WRITE setName)           // 由于QQmlListProperty的機制,即使我們沒有定義該屬性的WRITE功能,它也是可改變的

//![1]
public:
//![1]
    PieChart(QQuickItem *parent = 0);

    QString name() const;
    void setName(const QString &name);

//![2]
    QQmlListProperty<PieSlice> slices();     // 我們在屬性中僅僅定義了可讀性,是以這裡并沒有聲明setSlices()函數

private:
    static void append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice);   // 一個向向清單中添加屬性成員的函數

    QString m_name;
    QList<PieSlice *> m_slices;                    // 定義一個對應的資料成員
};
//![2]

#endif
           

piechart.cpp:

#include "piechart.h"
#include "pieslice.h"

PieChart::PieChart(QQuickItem *parent)
    : QQuickItem(parent)
{
}

QString PieChart::name() const
{
    return m_name;
}

void PieChart::setName(const QString &name)
{
    m_name = name;
}

//![0]
QQmlListProperty<PieSlice> PieChart::slices()               // 用來傳回清單中的屬性
{
    return QQmlListProperty<PieSlice>(this, 0, &PieChart::append_slice, 0, 0, 0); // 該函數原型如下圖
}

void PieChart::append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice)  // 每當我們向slices中添加一個PieSlice都會調用這個靜态的内部函數
{
    PieChart *chart = qobject_cast<PieChart *>(list->object);  // 取得清單的父對象
    if (chart) {                                               // 并設定為新屬性成員的父對象
        slice->setParentItem(chart);
        chart->m_slices.append(slice);
    }
}
//![0]
           
Qt5官方demo解析集19——Chapter 5: Using List Property Types

pieslice.h:

#ifndef PIESLICE_H
#define PIESLICE_H

#include <QtQuick/QQuickPaintedItem>
#include <QColor>

//![0]
class PieSlice : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor)
    Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle)  // 添加了扇形的起始角與角度範圍屬性
    Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan)  // 用來繪制餅狀圖的多個扇形的不同顔色
//![0]

public:
    PieSlice(QQuickItem *parent = 0);

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

    int fromAngle() const;
    void setFromAngle(int angle);

    int angleSpan() const;
    void setAngleSpan(int span);

    void paint(QPainter *painter);

private:
    QColor m_color;
    int m_fromAngle;                 // 注意與定義的屬性類型對應
    int m_angleSpan;
};

#endif
           

pieslice.cpp:

#include "pieslice.h"

#include <QPainter>

PieSlice::PieSlice(QQuickItem *parent)
    : QQuickPaintedItem(parent)
{
}

QColor PieSlice::color() const
{
    return m_color;
}

void PieSlice::setColor(const QColor &color)
{
    m_color = color;
}

int PieSlice::fromAngle() const
{
    return m_fromAngle;
}

void PieSlice::setFromAngle(int angle)
{
    m_fromAngle = angle;
}

int PieSlice::angleSpan() const
{
    return m_angleSpan;
}

void PieSlice::setAngleSpan(int angle)
{
    m_angleSpan = angle;
}

void PieSlice::paint(QPainter *painter)             
{
    QPen pen(m_color, 2);
    painter->setPen(pen);
    painter->setRenderHints(QPainter::Antialiasing, true);
    painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), m_fromAngle * 16, m_angleSpan * 16);
}
           

app.qml:

import Charts 1.0
import QtQuick 2.0

Item {
    width: 300; height: 200

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

        slices: [                           // 使用中括号括起清單中的成員
            PieSlice { 
                anchors.fill: parent
                color: "red"
                fromAngle: 0; angleSpan: 110 
            },
            PieSlice { 
                anchors.fill: parent
                color: "black"
                fromAngle: 110; angleSpan: 50 
            },
            PieSlice { 
                anchors.fill: parent
                color: "blue"
                fromAngle: 160; angleSpan: 100
            }
        ]
    }
}
           

運作效果如下:

Qt5官方demo解析集19——Chapter 5: Using List Property Types