How to draw a linear gradient arc with Qt QPainter?

I am trying to develop a custom QProgressBar that will look like this:

enter image description here

I created a class that extends QProgressBar and implemented paintEvent ():

 void CircularProgressBar::paintEvent(QPaintEvent*) { int progress = this->value(); int progressInDegrees = (double)(progress*360)/100; int barWidth = 20; QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, barWidth, Qt::SolidLine,Qt::RoundCap)); painter.drawArc(barWidth/2, barWidth/2, this->width() - barWidth, this->height() - barWidth, 90*16, progressInDegrees*-16);} 

This works great to draw a circular progress bar, but I have problems with the linear gradient of the panel color. I tried to create a QPen with a QLinearGradient object, and I tried to set the QPainter brush to a QLinearGradient object, but none of the strategies worked. Is it possible to draw an arc with a QPainter that has a linear gradient color?

+7
qt linear-gradients qpainter
source share
2 answers

I know this is an old question, but I came across it a few days ago, and I think I have a solution. You want to create a conical gradient and fix the drive that you want to use as a round loading bar. Here is an example:

widget.h:

 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class QPaintEvent; class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void setLoadingAngle(int loadingAngle); int loadingAngle() const; void setDiscWidth(int width); int discWidth() const; protected: void paintEvent(QPaintEvent *); private: int m_loadingAngle; int m_width; }; #endif // WIDGET_H 

widget.cpp:

 #include "widget.h" #include <QPaintEvent> #include <QPainter> #include <QConicalGradient> #include <QPen> Widget::Widget(QWidget *parent) : QWidget(parent), m_loadingAngle(0), m_width(0) { } Widget::~Widget() { } void Widget::setLoadingAngle(int loadingAngle) { m_loadingAngle = loadingAngle; } int Widget::loadingAngle() const { return m_loadingAngle; } void Widget::setDiscWidth(int width) { m_width = width; } int Widget::discWidth() const { return m_width; } void Widget::paintEvent(QPaintEvent *) { QRect drawingRect; drawingRect.setX(rect().x() + m_width); drawingRect.setY(rect().y() + m_width); drawingRect.setWidth(rect().width() - m_width * 2); drawingRect.setHeight(rect().height() - m_width * 2); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QConicalGradient gradient; gradient.setCenter(drawingRect.center()); gradient.setAngle(90); gradient.setColorAt(0, QColor(178, 255, 246)); gradient.setColorAt(1, QColor(5, 44, 50)); int arcLengthApproximation = m_width + m_width / 3; QPen pen(QBrush(gradient), m_width); pen.setCapStyle(Qt::RoundCap); painter.setPen(pen); painter.drawArc(drawingRect, 90 * 16 - arcLengthApproximation, -m_loadingAngle * 16); } 

main.cpp:

 #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.setDiscWidth(20); w.setLoadingAngle(270); w.show(); return a.exec(); } 

And the result:

enter image description here

Of course, this is not a complete and accurate solution, but I think that this is all you need to know in order to achieve what you want. The remaining details are not difficult to implement.

+6
source share

This solution is not quite what you need; the gradient goes from top to bottom, not around the circle:

 #include <QtWidgets> class Widget : public QWidget { public: Widget() { resize(200, 200); } void paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); const QRectF bounds(0, 0, width(), height()); painter.fillRect(bounds, "#1c1c1c"); QPen pen; pen.setCapStyle(Qt::RoundCap); pen.setWidth(20); QLinearGradient gradient; gradient.setStart(bounds.width() / 2, 0); gradient.setFinalStop(bounds.width() / 2, bounds.height()); gradient.setColorAt(0, "#1c1c1c"); gradient.setColorAt(1, "#28ecd6"); QBrush brush(gradient); pen.setBrush(brush); painter.setPen(pen); QRectF rect = QRectF(pen.widthF() / 2.0, pen.widthF() / 2.0, width() - pen.widthF(), height() - pen.widthF()); painter.drawArc(rect, 90 * 16, 0.65 * -360 * 16); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Widget w; w.show(); return app.exec(); } 

However, this is an arc with a linear gradient !: P

+2
source share

All Articles