Как расширить прямоугольник QML в C

#qt #qml #qtquick2 #qt-quick

#qt #qml #qtquick2 #qt-быстрый

Вопрос:

Когда я хочу создать новый элемент Qt Quick в C , я расширяю QQuickItem. Бывает, что я хочу, чтобы мой новый элемент имел те же основные свойства прямоугольника. Есть ли какой-либо класс, который я могу расширить, чтобы иметь прямоугольник напрямую?

Ответ №1:

Прямоугольник на самом деле является QQuickRectangle, но он не экспортируется для использования в C . Заголовочный файл QtQuick private qquickrectangle_p.h .

Комментарии:

1. затем, после его включения, мы должны просто следовать процедуре расширения , чтобы получить рабочий компонент?

2. @CapelliC, класс не экспортируется в Qt5Quick.lib. Таким образом, он не предназначен для использования в C . Вам необходимо изменить включаемый файл для экспорта класса (или определить Q_AUTOTEST_EXPORT, как описано в qt-project.org/wiki/Qt_Autotest_Environment ), затем перестроить Qt5Quick. библиотека, чтобы иметь возможность использовать ее в C .

Ответ №2:

Проверьте мою версию an AdvancedRectangle , которая может иметь разный радиус для каждого угла. Мне пришлось заново реализовать поведение прямоугольника.

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.

Комментарии:

1. Это не повторная реализация Rectangle , а реализация AdvancedRectangle . Rectangle есть QQuickItem и AdvancedRectangle есть QQuickPaintedItem .

2. можете ли вы объяснить, как создавать наши пользовательские быстрые типы qt с помощью opengl rendering fbos , например, в статье?

3. Просто и эффективно. Недостатком этого подхода является то, что он не будет ускоряться с помощью GPU, поскольку все рисуется с помощью QPainter на CPU. Не рекомендуется, если вам требуется, чтобы их было много в сцене.