Important: Please read the Qt Code of Conduct -

[SOLVED] Painting gradients with QGraphicsItem

  • Hello everyone,
    I want to draw a QGraphicsItem and fill it with a QLinearGradient.
    I've subclassed the Item implemented the paint function for testig like this:

        QLinearGradient gradient(m_BoxSize.topLeft(), m_BoxSize.bottomRight());
        gradient.setColorAt(0, Qt::green);
        gradient.setColorAt(1, Qt::red);
        painter->fillPath(shape(), gradient);
        painter->strokePath(shape(), QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    m_BoxSize is a member variable of my Item and set to QRectF(0, 0, 40, 40);
    and shape() is implemented like this:

        QPainterPath path;
        path.addRoundedRect(m_BoxSize, 5, 5);
        return path;

    When I add such an Item to my Scene, I'm getting a red rounded rect without infill.
    When I change painter->fillPath(shape(), gradient); to painter->fillPath(shape(), Qt::red); I'm getting a red rounded rect as expected.

    Can someone tell me my mistake?

    Thank you in advance and kind regards

    Edit: why aren't the code blocks working?

    [edit: Fixed coding tags, use ``` SGaist]
    ->Edit: Thank you :)

  • Lifetime Qt Champion


    Can you share the complete class code ?

  • Hi,
    yes, here it is:

    namespace Graphics
        namespace Items
            class ClassItem : public QGraphicsItem
                ClassItem(const QColor &color, const QPoint &position, QGraphicsScene *scene);
                virtual QRectF boundingRect() const override;
                virtual QPainterPath shape() const override;
                virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override;
                QColor m_Color;
                QPoint m_Position;
                QRectF m_BoxSize;
                QPainterPath m_ShapePath;
                QLinearGradient m_TitleGradient;
                QGraphicsScene *m_pScene;
            public slots:
                void resize(const QRectF &newRect);

    and the implementation

    Graphics::Items::ClassItem::ClassItem(const QColor &color, const QPoint &position, QGraphicsScene *scene) :
        setFlags(ItemIsSelectable | ItemIsMovable);
        m_TitleGradient.setColorAt(0, Qt::red);
        m_TitleGradient.setColorAt(1, Qt::blue);
        resize(QRectF(0, 0, 40, 40));
    void Graphics::Items::ClassItem::resize(const QRectF &newRect)
        m_BoxSize = newRect;
        m_ShapePath = QPainterPath();
        m_ShapePath.addRoundedRect(newRect, 5, 5);
    QPainterPath Graphics::Items::ClassItem::shape() const
        return m_ShapePath;
    void Graphics::Items::ClassItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
        painter->fillPath(m_ShapePath, m_TitleGradient);
        painter->strokePath(m_ShapePath, QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    It looks very different now, I've reimplemented it. My problem persists:
    the example code "ignores" the fillPath line but
    painter->fillPath(m_ShapePath, Qt::green);

    Kind regards

  • Any ideas on that?

    Tanks in advance and have a nice day :)

  • Check gradient fill mode:

    // ...
    resize(QRectF(0, 0, 40, 40));

    ObjectBoundingMode accepts range 0 -> 1.
    Check LogicalMode (default mode).

  • Thank you for your answere. I've already tried that but it wasn't the solution. I've figured out that the problem occures when turning on OpenGL rendering. I guess it has to do with my hibryd graphic system. My main card has some serious problems so I can't run Optirun right now and I guess my secondary GPU does not support the required features (only OpenGL 3.X).
    I'm not shure about that but as I said: turning off the OpenGL rendering solved that problem for me. Maybe it helps others.

    Have a nice day everyone