如何在C ++中扩展QML Rectangle

时间:2014-06-29 20:42:03

标签: qt qt-quick qtquick2

当我想在C ++中创建一个新的Qt Quick Item时,我扩展了QQuickItem。碰巧我希望我的新项目具有与Rectangle相同的基本属性。是否有任何类可以扩展为直接使用Rectangle?

2 个答案:

答案 0 :(得分:2)

Rectangle实际上是 QQuickRectangle ,但它不会被导出以用于C ++。头文件是 QtQuick \ private \ qquickrectangle_p.h

答案 1 :(得分:0)

检查我的AdvancedRectangle版本,每个角落的半径可以不同。我不得不重新实现Rectangle的行为。

advancedrectangle.h

#ifndef ADVANCEDRECTANGLE_H
#define ADVANCEDRECTANGLE_H

#include <QQuickPaintedItem>
#include <QPainter>
#include <QPen>

class AdvancedRectangle : public QQuickPaintedItem
{
    Q_OBJECT
public:
    explicit AdvancedRectangle(QQuickItem *parent = 0);

    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    QColor color() const;
    void setColor(QColor color);

    Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
    qreal radius() const;
    void setRadius(qreal r);

    Q_PROPERTY(qreal radiusTopLeft READ radiusTopLeft WRITE setRadiusTopLeft NOTIFY radiusTopLeftChanged)
    qreal radiusTopLeft() const;
    void setRadiusTopLeft(qreal r);

    Q_PROPERTY(qreal radiusTopRight READ radiusTopRight WRITE setRadiusTopRight NOTIFY radiusTopRightChanged)
    qreal radiusTopRight() const;
    void setRadiusTopRight(qreal r);

    Q_PROPERTY(qreal radiusBottomRight READ radiusBottomRight WRITE setRadiusBottomRight NOTIFY radiusBottomRightChanged)
    qreal radiusBottomRight() const;
    void setRadiusBottomRight(qreal r);

    Q_PROPERTY(qreal radiusBottomLeft READ radiusBottomLeft WRITE setRadiusBottomLeft NOTIFY radiusBottomLeftChanged)
    qreal radiusBottomLeft() const;
    void setRadiusBottomLeft(qreal r);

    void paint(QPainter *painter);

    enum START_ANGELS {
        START_E = 0,
        START_N = 90,
        START_W = 180,
        START_S = 270
    };

signals:
    void colorChanged();
    void radiusChanged();
    void radiusTopLeftChanged();
    void radiusTopRightChanged();
    void radiusBottomRightChanged();
    void radiusBottomLeftChanged();

public slots:


private:
    QColor color_ = QColor(255, 255, 255);
    qreal radius_ = 0.0;
    qreal radiusTopLeft_ = -1;
    qreal radiusTopRight_ = -1;
    qreal radiusBottomRight_ = -1;
    qreal radiusBottomLeft_ = -1;

private slots:
    void onAppearanceChanged();
};

#endif // ADVANCEDRECTANGLE_H

advancedrectangle.cpp

#include "advancedrectangle.h"

AdvancedRectangle::AdvancedRectangle(QQuickItem *parent) :
    QQuickPaintedItem(parent)
{
    connect(this, SIGNAL(widthChanged()), SLOT(onAppearanceChanged()));
    connect(this, SIGNAL(heightChanged()), SLOT(onAppearanceChanged()));
    connect(this, SIGNAL(colorChanged()), SLOT(onAppearanceChanged()));
}

QColor AdvancedRectangle::color() const
{
    return color_;
}

void AdvancedRectangle::setColor(QColor color)
{
    if (color_ == color) return;

    color_ = color;
    emit colorChanged();
}

qreal AdvancedRectangle::radius() const
{
    return radius_;
}

void AdvancedRectangle::setRadius(qreal r)
{
    if (r == radius_) return;

    radius_ = r;
    emit radiusChanged();
}

qreal AdvancedRectangle::radiusTopLeft() const
{
    if (radiusTopLeft_ >= 0) return radiusTopLeft_;
    else return radius_;
}

void AdvancedRectangle::setRadiusTopLeft(qreal r)
{
    if (r == radiusTopLeft_) return;

    radiusTopLeft_ = r;
    emit radiusTopLeftChanged();
}

qreal AdvancedRectangle::radiusTopRight() const
{
    if (radiusTopRight_ >= 0) return radiusTopRight_;
    else return radius_;
}

void AdvancedRectangle::setRadiusTopRight(qreal r)
{
    if (r == radiusTopRight_) return;

    radiusTopRight_ = r;
    emit radiusTopRightChanged();
}

qreal AdvancedRectangle::radiusBottomRight() const
{
    if (radiusBottomRight_ >= 0) return radiusBottomRight_;
    else return radius_;
}

void AdvancedRectangle::setRadiusBottomRight(qreal r)
{
    if (r == radiusBottomRight_) return;

    radiusBottomRight_ = r;
    emit radiusBottomRightChanged();
}

qreal AdvancedRectangle::radiusBottomLeft() const
{
    if (radiusBottomLeft_ >= 0) return radiusBottomLeft_;
    else return radius_;
}

void AdvancedRectangle::setRadiusBottomLeft(qreal r)
{
    if (r == radiusBottomLeft_) return;

    radiusBottomLeft_ = r;
    emit radiusBottomLeftChanged();
}

void AdvancedRectangle::paint(QPainter *painter)
{
    QPen pen(Qt::NoPen);
    painter->setPen(pen);

    QBrush brush(color_);
    painter->setBrush(brush);

    painter->setRenderHints(QPainter::Antialiasing, true);

    int _width = width();
    int _height = height();

    QRectF rectangle;
    // top-left
    rectangle = QRectF(0, 0, 2*radiusTopLeft(), 2*radiusTopLeft());
    painter->drawPie(rectangle, START_W * 16, 90 * -1 * 16);

    // top-right
    rectangle = QRectF(_width-2*radiusTopRight(), 0, 2*radiusTopRight(), 2*radiusTopRight());
    painter->drawPie(rectangle, START_N * 16, 90 * -1 * 16);

    // bottom-right
    rectangle = QRectF(_width-2*radiusBottomRight(), _height-2*radiusBottomRight(), 2*radiusBottomRight(), 2*radiusBottomRight());
    painter->drawPie(rectangle, START_E * 16, 90 * -1 * 16);

    // bottom-left
    rectangle = QRectF(0, _height-2*radiusBottomLeft(), 2*radiusBottomLeft(), 2*radiusBottomLeft());
    painter->drawPie(rectangle, START_S * 16, 90 * -1 * 16);

    QPointF points[12] = {
        QPointF(radiusTopLeft(), 0),
        QPointF(radiusTopLeft(), radiusTopLeft()),
        QPointF(0, radiusTopLeft()),
        QPointF(0, _height-radiusBottomLeft()),
        QPointF(radiusBottomLeft(), _height-radiusBottomLeft()),
        QPointF(radiusBottomLeft(), _height),
        QPointF(_width-radiusBottomRight(), _height),
        QPointF(_width-radiusBottomRight(), _height-radiusBottomRight()),
        QPointF(_width, _height-radiusBottomRight()),
        QPointF(_width, radiusTopRight()),
        QPointF(_width-radiusTopRight(), radiusTopRight()),
        QPointF(_width-radiusTopRight(), 0)
    };
    painter->drawPolygon(points, 12);
}

void AdvancedRectangle::onAppearanceChanged()
{
    int new_width = width();
    int new_height = height();
    update(QRect(0, 0, new_width, new_height));
}

如果您需要MIT许可,请告诉我。