Qt Write Custom Control 50-Mini Dashboard

Posted by petrosa on Tue, 13 Aug 2019 03:39:21 +0200

1. Preface

This control is named Mini Dashboard because it can be reduced to a very small area display. It is very suitable for small area display of instrument data. It can also be manually touched to adjust the progress. It is one of the most beautiful and compact controls I personally think.The first time you see a similar control is in a music video editing software, used to show the volume of the left channel and the right channel. There are many similar mini-dashboards in the whole software system, users can slide and adjust directly with the mouse to display the largest information in the smallest occupied area, beautiful!
This control also expands the display of left and right equal parts, such as the middle value is 0, the left side is the value area below 0, and the right side is the value area above 0. The progress is different, supporting the setting of left and right rotation angle and various color settings.

2. Functions realized

  • 1:Support Indicator Style Selection Line Indicator/Pointer Indicator/Rounded Pointer Indicator/Triangle Indicator
  • 2:Supports mouse-down rotation changes
  • 3:Supports negative scale values
  • 4:Support setting current and range values
  • 5:Support left and right rotation setting
  • 6:Support setting scale quantity
  • 7:Support setting border/background/text/progress color
  • 8:Supports setting whether left and right values are displayed equally

3. Effect Charts

4. Header File Code

#ifndef GAUGEMINI_H
#define GAUGEMINI_H

/**
 * Author of mini dashboard control: feiyangqingyun(QQ:517216493) 2017-11-26
 * 1:Supports Indicator Style Selection Line Indicator/Pointer Indicator/Rounded Pointer Indicator/Triangle Indicator
 * 2:Supports mouse-down rotation to change values
 * 3:Supports negative scale values
 * 4:Support setting current and range values
 * 5:Support left and right rotation angle setting
 * 6:Support setting scale quantity
 * 7:Support for setting border/background/text/progress colors
 * 8:Supports setting whether left and right values are displayed equally
 */

#include <QWidget>

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT GaugeMini : public QWidget
#else
class GaugeMini : public QWidget
#endif

{
    Q_OBJECT
    Q_ENUMS(PointerStyle)

    Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
    Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
    Q_PROPERTY(double value READ getValue WRITE setValue)
    Q_PROPERTY(int precision READ getPrecision WRITE setPrecision)

    Q_PROPERTY(int step READ getStep WRITE setStep)
    Q_PROPERTY(int startAngle READ getStartAngle WRITE setStartAngle)
    Q_PROPERTY(int endAngle READ getEndAngle WRITE setEndAngle)

    Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor)
    Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
    Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
    Q_PROPERTY(QColor percentColor READ getPercentColor WRITE setPercentColor)

    Q_PROPERTY(bool doublePercent READ getDoublePercent WRITE setDoublePercent)
    Q_PROPERTY(bool showValue READ getShowValue WRITE setShowValue)
    Q_PROPERTY(PointerStyle pointerStyle READ getPointerStyle WRITE setPointerStyle)

public:
    enum PointerStyle {
        PointerStyle_Line = 0,          //Line Indicator
        PointerStyle_Indicator = 1,     //Pointer Indicator
        PointerStyle_IndicatorR = 2,    //Rounded Pointer Indicator
        PointerStyle_Triangle = 3       //Triangle indicator
    };

    explicit GaugeMini(QWidget *parent = 0);
    ~GaugeMini();

protected:
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void paintEvent(QPaintEvent *);
    void drawScale(QPainter *painter);
    void drawBgCircle(QPainter *painter);
    void drawCenterCircle(QPainter *painter);
    void drawPointerLine(QPainter *painter);
    void drawPointerIndicator(QPainter *painter);
    void drawPointerIndicatorR(QPainter *painter);
    void drawPointerTriangle(QPainter *painter);
    void drawValue(QPainter *painter);

private:
    double minValue;                //minimum value
    double maxValue;                //Maximum
    double value;                   //target value
    int precision;                  //Precision, the last few decimal places

    int step;                       //Number of scales
    int startAngle;                 //Start Rotation Angle
    int endAngle;                   //End Rotation Angle

    QColor borderColor;             //Border color
    QColor bgColor;                 //background color
    QColor textColor;               //Text color
    QColor percentColor;            //Progress color

    bool doublePercent;             //Is the range value halved
    bool showValue;                 //Whether to display the current value
    PointerStyle pointerStyle;      //Pointer Style

private:
    //Whether the mouse is pressed or not
    bool pressed;
    //Set the value at the currently pressed coordinate according to the coordinates that the mouse is pressing
    void setPressedValue(QPointF pressedPoint);

public:
    double getMinValue()            const;
    double getMaxValue()            const;
    double getValue()               const;
    int getPrecision()              const;

    int getStep()                   const;
    int getStartAngle()             const;
    int getEndAngle()               const;

    QColor getBorderColor()         const;
    QColor getBgColor()             const;
    QColor getTextColor()           const;
    QColor getPercentColor()        const;

    bool getDoublePercent()         const;
    bool getShowValue()             const;
    PointerStyle getPointerStyle()  const;

    QSize sizeHint()                const;
    QSize minimumSizeHint()         const;

public Q_SLOTS:
    //Set range value
    void setRange(double minValue, double maxValue);
    void setRange(int minValue, int maxValue);

    //Set Maximum and Minimum Values
    void setMinValue(double minValue);
    void setMaxValue(double maxValue);

    //Set Target Value
    void setValue(double value);
    void setValue(int value);

    //Set Accuracy
    void setPrecision(int precision);

    //Set the number of scales
    void setStep(int step);
    //Set the start rotation angle
    void setStartAngle(int startAngle);
    //Set end rotation angle
    void setEndAngle(int endAngle);

    //border-color
    void setBorderColor(const QColor &borderColor);
    //Set background color
    void setBgColor(const QColor &bgColor);
    //Set Text Color
    void setTextColor(const QColor &textColor);
    //Set progress color
    void setPercentColor(const QColor &percentColor);

    //Set whether to halve range values
    void setDoublePercent(bool doublePercent);
    //Set whether the current value is displayed
    void setShowValue(bool showValue);
    //Set pointer style
    void setPointerStyle(const PointerStyle &pointerStyle);

Q_SIGNALS:
    void valueChanged(double value);
};

#endif // GAUGEMINI_H


5. Core Code

void GaugeMini::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //Drawing preparation, anti-aliasing enabled, axis center shifted, equal scale scaling
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    //Draw scale lines
    drawScale(&painter);
    //Draw Background Circle
    drawBgCircle(&painter);
    //Draw Center Circle
    drawCenterCircle(&painter);

    //Draw indicator according to indicator shape
    if (pointerStyle == PointerStyle_Line) {
        drawPointerLine(&painter);
    } else if (pointerStyle == PointerStyle_Indicator) {
        drawPointerIndicator(&painter);
    } else if (pointerStyle == PointerStyle_IndicatorR) {
        drawPointerIndicatorR(&painter);
    } else if (pointerStyle == PointerStyle_Triangle) {
        drawPointerTriangle(&painter);
    }

    //Draw current value
    drawValue(&painter);
}

void GaugeMini::drawScale(QPainter *painter)
{
    int radius = 96;
    int offset = 10;
    painter->save();

    painter->rotate(startAngle);
    double angleStep = (360.0 - startAngle - endAngle) / step;
    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (value - minValue);

    QPen pen;
    pen.setWidthF(5.0);
    pen.setCapStyle(Qt::RoundCap);

    double rotate = 0;
    for (int i = 0; i <= step; i++) {
        if (doublePercent) {
            bool right = i >= (step / 2);
            if (!right) {
                pen.setColor((rotate < degRotate) ? textColor : percentColor);
            } else {
                pen.setColor((rotate <= degRotate) ? percentColor : textColor);
            }

            //First grid color when correcting left minimum
            if (value == minValue && !right) {
                pen.setColor(percentColor);
            }

            //Middle grid color when correcting left values
            if (value <= ((maxValue - minValue) / 2 + minValue) && i == (step / 2)) {
                pen.setColor(percentColor);
            }

            //Correct Middle Value Middle Grid Color
            if (value == ((maxValue - minValue) / 2 + minValue)) {
                pen.setColor(textColor);
            }
        } else {
            if (rotate <= degRotate) {
                pen.setColor(percentColor);
            } else {
                pen.setColor(textColor);
            }

            //First grid color when correcting left minimum
            if (value == minValue) {
                pen.setColor(textColor);
            }
        }

        painter->setPen(pen);
        painter->drawLine(0, radius - offset, 0, radius);
        painter->rotate(angleStep);
        rotate += angleStep;
    }

    painter->restore();
}

void GaugeMini::drawBgCircle(QPainter *painter)
{
    int radius = 75;
    painter->save();

    QPen pen;
    pen.setWidthF(5.0);
    pen.setColor(borderColor);

    painter->setPen(pen);
    painter->setBrush(bgColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);

    painter->restore();
}

void GaugeMini::drawCenterCircle(QPainter *painter)
{
    int radius = 15;
    painter->save();

    QColor color = percentColor;
    if (doublePercent) {
        bool center = (value == (maxValue - minValue) / 2 + minValue);
        color = center ? borderColor : percentColor;
    }

    painter->setPen(Qt::NoPen);
    painter->setBrush(color);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);

    painter->restore();
}

6. Introduction to Controls

  1. Over 150 beautiful controls, including dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlight buttons, slide selectors, lunar calendar, etc.Far more than qwt integrated controls.
  2. Each class can be separated into a single control, with zero coupling, a header file and an implementation file for each control, independent of other files, so that a single control can be integrated into the project as a source code with less code.qwt's control classes are linked and highly coupled. To use one of these controls, you must include all the code.
  3. All pure Qt writing, QWidget+QPainter drawing, support any Qt version from Qt4.6 to Qt5.12, support compilers such as mingw, msvc, gcc, support any operating system such as windows+linux+mac+embedded linux, no scrambling, can be directly integrated into Qt Creator, like its own controls, most of the effects as long as setA few attributes are very convenient.
  4. Each control has a corresponding separate DEMO containing its source code for easy reference.It also provides an integrated DEMO used by all controls.
  5. Each control's source code has detailed Chinese comments, which are written in accordance with the uniform design specifications to facilitate learning how to write custom controls.
  6. The default and demo colors for each control are beautiful.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls offer a variety of style choices and indicator style choices.
  9. All controls adapt to form stretch changes.
  10. Integrates custom control property designer, supports drag design, what you see is what you get, and supports import and export xml formats.
  11. With its own activex control demo, all controls can run directly in the ie browser.
  12. Integrate fontawesome graphics fonts + several hundred graphics fonts from Alibaba iconfont collection to enjoy graphics fonts.
  13. All controls end up with a dynamic library file (dll or so, etc.) that can be integrated directly into the qtcreator and dragged for design use.
  14. There is already a qml version, and the pyqt version will be considered later if there is a large user demand.
  15. Custom Control Plugins open dynamic library for use (permanently free) without any backdoors or restrictions, please use with confidence.
  16. There are currently 26 versions of dll available, including qt5.12.3 msvc2017 32+64 mingw 32+64.
  17. Add controls and improve controls at irregular intervals, update SDK at irregular intervals, welcome to make suggestions, thank you!
  18. Qt introductory books recommend Hoyafei's Quick Start Qt Creator, Getting Started with Qt5 Programming, and Qt advanced books recommend the official C++ GUI Qt4 Programming.
  19. It is highly recommended that programmers self-cultivate and plan series "Talking Programmers", "Programmers'Growth Class" and "Relieving Programmers", which benefits a lot and benefits for a lifetime!
  20. SDK Download Link: https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ Extraction code: 877p
  21. The download link includes various versions of dynamic library files, header files for all controls, demo, custom controls + property designer.
  22. widget version (QQ:517216493) qml version (QQ:373955953) three-camel (QQ:278969898).
  23. Taoge's Knowledge Column Qt Road to Advancement https://zhuanlan.zhihu.com/TaoQt
  24. Welcome to the WeChat Public Number, C++/Python, learning methods, writing skills, popular technologies, career development and so on. There are lots of dry goods and benefits!

Topics: Qt Qt5 Linux SDK