QRect getEllipseRect(const QPoint ¢er, int rx, int ry)
return QRect(center.x() - rx, center.y() - ry, 2 * rx, 2 * ry);
struct Graphical_DashboardPrivate
int maximumScaleValue{280};
QColor backgroundColor{"#ff000000"};
QColor borderGradient_topLeftColor{"#ffffffff"};
QColor borderGradient_bottomRightColor{"#ff000000"};
QColor scaleColor{"#ffffffff"};
QColor scaleValueColor{"#ffffffff"};
QColor pointerBorderColor{"#ffffffff"};
QColor pointerbackgroundColor{"#ffA0A0A0"};
QColor centralWheelGradient_insideColor{"#ff808080"};
QColor centralWheelGradient_outsideColor{"#ffffffff"};
int pointerBorderWidth{3};
int centralWheelRadius{26};
void calculateClockwiseRange();
void drawFrame(QPainter &painter);
void drawScale(QPainter &painter);
void drawScaleReadings(QPainter &painter);
void drawPointer(QPainter &painter);
void Graphical_DashboardPrivate::calculateClockwiseRange()
if(maximumScaleValue >= 180)
startAngle = (360 - maximumScaleValue) / 2 + 90;
endAngle = (startAngle + maximumScaleValue) % 360;
anglePerVel = (360.0 - (startAngle - endAngle)) / maximumScaleValue;
startAngle = 270 - (maximumScaleValue/2);
endAngle = startAngle + maximumScaleValue;
anglePerVel = (endAngle - startAngle) / maximumScaleValue;
void Graphical_DashboardPrivate::drawFrame(QPainter &painter)
static QPoint origin{0,0};
painter.setPen(Qt::transparent);
QLinearGradient lg(-500,-500,500,500);
lg.setColorAt(0,borderGradient_topLeftColor);
lg.setColorAt(1,borderGradient_bottomRightColor);
auto rect = getEllipseRect(origin,500,500);
int newHeight = rect.height() / 2;
rect.setHeight(newHeight + 50);
painter.setClipRect(rect);
painter.drawEllipse(origin,480,480);
auto rect = getEllipseRect(origin,430,430);
painter.setClipPath(path);
int newHeight = rect.height() / 2;
rect.setHeight(newHeight+12);
painter.fillRect(rect,backgroundColor);
void Graphical_DashboardPrivate::drawScale(QPainter &painter)
painter.rotate(startAngle);
int step = maximumScaleValue / 5;
if(maximumScaleValue >= 180)
angleStep = (360.0 - (startAngle - endAngle)) / step;
angleStep = (endAngle - startAngle) / step;
for (int i = 0; i <= maximumScaleValue; i += 5)
painter.setPen(QPen(scaleColor,10));
painter.drawLine(420, 0, 340, 0);
painter.setPen(QPen(scaleColor,6));
painter.drawLine(420, 0, 380, 0);
painter.setPen(QPen(scaleColor,4));
painter.drawLine(400, 0, 380, 0);
painter.rotate(angleStep);
void Graphical_DashboardPrivate::drawScaleReadings(QPainter &painter)
painter.setPen(scaleValueColor);
qreal x,y,w,h,angle,angleArc;
auto font = painter.font();
for (int i = 0; i <= maximumScaleValue; i+= 20)
angle = 360 - (startAngle + i * anglePerVel);
angleArc = angle * 3.14 / 180;
y = -280 * sin(angleArc);
QString speed = QString::number(i * maximumValue/maximumScaleValue);
painter.drawText(QPointF(x - w / 2,y + h/4),speed);
void Graphical_DashboardPrivate::drawPointer(QPainter &painter)
int currentValue = maximumScaleValue/2;
float curAngle = startAngle + currentValue * anglePerVel;
painter.rotate(curAngle);
QRadialGradient haloGradient(0, 0, 60, 0, 0);
haloGradient.setColorAt(0, pointerbackgroundColor.darker());
haloGradient.setColorAt(1, pointerbackgroundColor);
if(pointerBorderWidth == 0)
painter.setPen(Qt::transparent);
painter.setPen(QPen(pointerBorderColor,pointerBorderWidth));
painter.setBrush(haloGradient);
QPointF(0.0, centralWheelRadius/2),
QPointF(0.0, -centralWheelRadius/2),
painter.drawPolygon(points,3);
QRadialGradient rg(0,0,40);
rg.setColorAt(0.0,centralWheelGradient_insideColor);
rg.setColorAt(0.5,centralWheelGradient_outsideColor);
rg.setColorAt(1.0,centralWheelGradient_insideColor);
painter.setPen(Qt::NoPen);
painter.drawEllipse(QPoint(0,0),centralWheelRadius,centralWheelRadius);
Widget::Widget(QWidget *parent)
setPalette(QPalette(QPalette::Background,Qt::white));
d_ptr = new Graphical_DashboardPrivate;
d_ptr->calculateClockwiseRange();
void Widget::paintEvent(QPaintEvent *event)
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHints(QPainter::TextAntialiasing);
painter.setRenderHints(QPainter::SmoothPixmapTransform);
side = qMin(thisRect.width(), thisRect.height()*2);
side = qMin(thisRect.width(), thisRect.height()*2 - (side/20) * 2);
painter.translate(thisRect.width() / 2, thisRect.height() - side /20 );
side = qMin(thisRect.width(), thisRect.height());
painter.translate(thisRect.width() / 2, thisRect.height() / 2);
painter.scale(side / 1000.0, side / 1000.0);
d_ptr->drawFrame(painter);
d_ptr->drawScale(painter);
d_ptr->drawScaleReadings(painter);
d_ptr->drawPointer(painter);



