QML Gradient Any Direction - SOLVED



  • Good day

    I leave here a way to gradients in any direction.

    I make a new component called "Gradiente"

    Code in qt 5.0.1

    gradiente.h
    [code]
    #ifndef GRADIENTE_H
    #define GRADIENTE_H

    #include <QtCore>
    #include <QQuickPaintedItem>
    #include <QPainter>
    #include <QDebug>

    class Gradiente : public QQuickPaintedItem
    {
    Q_OBJECT
    Q_PROPERTY(QList<QString> colores
    READ colores
    WRITE setColores
    NOTIFY fondoChanged)

    Q_PROPERTY(QList<qreal> puntos
               READ puntos
               WRITE setPuntos
               NOTIFY fondoChanged)
    
    Q_PROPERTY(QPointF puntoInicial
               READ puntoInicial
               WRITE setPuntoInicial
               NOTIFY fondoChanged)
    
    Q_PROPERTY(QPointF puntoFinal
               READ puntoFinal
               WRITE setPuntoFinal
               NOTIFY fondoChanged)
    

    public:
    void setColores(const QList<QString> &cs);
    QList<QString> colores() const;
    void setPuntos(const QList<qreal> &ps);
    QList<qreal> puntos() const;
    void setPuntoInicial(const QPointF &p);
    void setPuntoFinal(const QPointF &p);
    QPointF puntoInicial() const;
    QPointF puntoFinal() const;

    signals:
    void fondoChanged();
    public:
    explicit Gradiente(QQuickPaintedItem *parent = 0);
    void paint(QPainter *painter);
    signals:

    public slots:

    private:
    QList<QString> m_colores;
    QList<qreal> m_puntos;
    QPointF m_pi;
    QPointF m_pf;

    };

    #endif // GRADIENTE_H
    [/code]

    gradiente.cpp
    [code]
    #include "gradiente.h"

    Gradiente::Gradiente(QQuickPaintedItem *parent) :
    QQuickPaintedItem(parent)
    {
    setFlag(ItemHasContents, true);
    }

    void Gradiente::paint(QPainter *painter)
    {
    //painter->setRenderHints(QPainter::Antialiasing, true);

    float x1 = m_pi.x() * this->width();
    float y1 = m_pi.y() * this->height();
    float x2 = m_pf.x() * this->width();
    float y2 = m_pf.y() * this->height();
    
    QLinearGradient linearGrad(x1,y1,x2,y2);
    
    for (int i = 0; i < m_colores.size(); i++) {
        if(i >= m_puntos.size()){
            qWarning() << "El vector de 'colores' y 'puntos' debe tener el mismo tamaño!";
            break;
        }
        else{
            linearGrad.setColorAt(m_puntos.at(i), m_colores.at(i));
        }
    }
    
    QBrush br(linearGrad);
    painter->fillRect(boundingRect(), br);
    

    }

    void Gradiente::setColores(const QList<QString> &cs)
    {
    m_colores = cs;
    emit fondoChanged();
    }

    QList<QString> Gradiente::colores() const
    {
    return m_colores;
    }

    void Gradiente::setPuntos(const QList<qreal> &ps)
    {
    m_puntos = ps;
    emit fondoChanged();
    }

    QList<qreal> Gradiente::puntos() const
    {
    return m_puntos;
    }

    void Gradiente::setPuntoInicial(const QPointF &p)
    {
    m_pi = p;
    if(m_pi.x() > 1) m_pi.setX(1);
    if(m_pi.y() > 1) m_pi.setY(1);
    emit fondoChanged();
    }

    void Gradiente::setPuntoFinal(const QPointF &p)
    {
    m_pf = p;
    if(m_pf.x() > 1) m_pf.setX(1);
    if(m_pf.y() > 1) m_pf.setY(1);
    emit fondoChanged();
    }

    QPointF Gradiente::puntoInicial() const
    {
    return m_pi;
    }

    QPointF Gradiente::puntoFinal() const
    {
    return m_pf;
    }
    [/code]

    Registred the new component.

    main.cpp
    [code]
    #include "gradiente.h"
    ......
    qmlRegisterType<Gradiente>("MisComponentes", 1, 0, "Gradiente");
    [/code]

    Finally, in the QML file:

    [code]
    import MisComponentes 1.0
    .....
    .........
    //Horizontal Gradient
    Gradiente{
    width: 400
    height: 400
    colores: ["red", "blue", "#2f548d"]
    puntos: [0.0 , 0.5, 1.0]
    puntoInicial.x: 0.0
    puntoInicial.y: 0.5
    puntoFinal.x: 1.0
    puntoFinal.y: 0.5
    }
    //Diagonal Gradient
    Gradiente{
    y: 450
    width: 400
    height: 400
    colores: ["red", "blue", "#2f548d"]
    puntos: [0.0 , 0.5, 1.0]
    puntoInicial.x: 0.0
    puntoInicial.y: 0.0
    puntoFinal.x: 1.0
    puntoFinal.y: 1.0
    }
    [/code]

    I hope this is helpful to you



  • Hi,

    This was exactly what I needed - somehow OpacityMask won't go well with traditional QML gradient+rotation

    Your Class solved it, thanks!

    Note: Qt 5.0.2


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.