您的位置:首页 > 编程语言 > Qt开发

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

2014-07-04 18:35 435 查看
本系列所有文章可以在这里查看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]




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


运行效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: