Qt实例分析——QML调用的C++类型添加自定义类型的属性列表

piechart.h:

#ifndef PIECHART_H
#define PIECHART_H
#include <QtQuick/QQuickItem>
class PieSlice;                    // 由于这里只使用了PieSlice的指针,我们可以使用前向声明
//![0]
class PieChart : public QQuickItem
{
    Q_OBJECT
<pre name="code" class="cpp" style="font-size: 14px; line-height: 26px;">// 我们使用QQmlListProperty<PieSlice>来定义slices属性的类型
<pre name="code" class="cpp" style="font-size: 14px; line-height: 26px;">// 该属性是一个PieSlice的列表,而QQmlListProperty则为我们提供了在QML中扩充该列表成员的能力
<pre name="code" class="cpp" style="font-size: 14px; line-height: 26px;">// 由于QQmlListProperty的机制,即使我们没有定义该属性的WRITE功能,它也是可改变的

 
 Q_PROPERTY(QQmlListProperty<PieSlice> slices READ slices) Q_PROPERTY(QString name READ name WRITE setName) //![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
            }
        ]
    }
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值