找回密码
 立即注册
收起左侧

Qt编写自定义控件6-指南针仪表盘

1
回复
4217
查看
[复制链接]
累计签到:7 天
连续签到:1 天
来源: 2019-4-23 23:03:41 显示全部楼层 |阅读模式
前言
指南针仪表盘,主要用来指示东南西北四个方位,双向对称两个指针旋转,其实就是360度打转,功能属于简单型,可能指针的绘制稍微难一点,需要计算多个点构成多边形,本系列控件文章将会连续发100+篇,一方面为了锻炼自己的毅力+坚持力,一方面为了宣传自己,如果各位对完整的源码有兴趣可以私聊,也欢迎在文章下面评论提出建议,谢谢!

实现的功能
* 1:可设置当前度数
* 2:可设置精确度
* 3:可设置是否启用动画及步长
* 4:可设置边框渐变颜色
* 5:可设置背景渐变颜色
* 6:可设置加深和明亮颜色
* 7:可设置指南指北指针颜色
* 8:可设置中心点渐变颜色

效果图


头文件代码
  1. #ifndef GAUGECOMPASS_H
  2. #define GAUGECOMPASS_H

  3. /**
  4. * 指南针仪表盘控件 作者:feiyangqingyun(QQ:517216493) 2016-11-12
  5. * 1:可设置当前度数
  6. * 2:可设置精确度
  7. * 3:可设置是否启用动画及步长
  8. * 4:可设置边框渐变颜色
  9. * 5:可设置背景渐变颜色
  10. * 6:可设置加深和明亮颜色
  11. * 7:可设置指南指北指针颜色
  12. * 8:可设置中心点渐变颜色
  13. */

  14. #include <QWidget>

  15. #ifdef quc
  16. #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
  17. #include <QtDesigner/QDesignerExportWidget>
  18. #else
  19. #include <QtUiPlugin/QDesignerExportWidget>
  20. #endif

  21. class QDESIGNER_WIDGET_EXPORT GaugeCompass : public QWidget
  22. #else
  23. class GaugeCompass : public QWidget
  24. #endif

  25. {
  26.         Q_OBJECT
  27.         Q_PROPERTY(double value READ getValue WRITE setValue)
  28.         Q_PROPERTY(int precision READ getPrecision WRITE setPrecision)

  29.         Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
  30.         Q_PROPERTY(double animationStep READ getAnimationStep WRITE setAnimationStep)

  31.         Q_PROPERTY(QColor crownColorStart READ getCrownColorStart WRITE setCrownColorStart)
  32.         Q_PROPERTY(QColor crownColorEnd READ getCrownColorEnd WRITE setCrownColorEnd)

  33.         Q_PROPERTY(QColor bgColorStart READ getBgColorStart WRITE setBgColorStart)
  34.         Q_PROPERTY(QColor bgColorEnd READ getBgColorEnd WRITE setBgColorEnd)

  35.         Q_PROPERTY(QColor darkColor READ getDarkColor WRITE setDarkColor)
  36.         Q_PROPERTY(QColor lightColor READ getLightColor WRITE setLightColor)

  37.         Q_PROPERTY(QColor foreground READ getForeground WRITE setForeground)
  38.         Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)

  39.         Q_PROPERTY(QColor northPointerColor READ getNorthPointerColor WRITE setNorthPointerColor)
  40.         Q_PROPERTY(QColor southPointerColor READ getSouthPointerColor WRITE setSouthPointerColor)

  41.         Q_PROPERTY(QColor centerColorStart READ getCenterColorStart WRITE setCenterColorStart)
  42.         Q_PROPERTY(QColor centerColorEnd READ getCenterColorEnd WRITE setCenterColorEnd)

  43. public:
  44.         explicit GaugeCompass(QWidget *parent = 0);
  45.     ~GaugeCompass();

  46. protected:
  47.         void paintEvent(QPaintEvent *);
  48.         void drawCrownCircle(QPainter *painter);
  49.         void drawBgCircle(QPainter *painter);
  50.         void drawScale(QPainter *painter);
  51.         void drawScaleNum(QPainter *painter);
  52.         void drawCoverOuterCircle(QPainter *painter);
  53.         void drawCoverInnerCircle(QPainter *painter);
  54.         void drawCoverCenterCircle(QPainter *painter);
  55.         void drawPointer(QPainter *painter);
  56.         void drawCenterCircle(QPainter *painter);
  57.     void drawValue(QPainter *painter);

  58. private:
  59.     double value;                   //目标值
  60.     int precision;                  //精确度,小数点后几位

  61.     bool animation;                 //是否启用动画显示
  62.     double animationStep;           //动画显示时步长

  63.     QColor crownColorStart;         //外边框渐变开始颜色
  64.     QColor crownColorEnd;           //外边框渐变结束颜色

  65.     QColor bgColorStart;            //背景渐变开始颜色
  66.     QColor bgColorEnd;              //背景渐变结束颜色

  67.     QColor darkColor;               //加深颜色
  68.     QColor lightColor;              //明亮颜色

  69.     QColor foreground;              //前景色
  70.     QColor textColor;               //文字颜色

  71.     QColor northPointerColor;       //北方指针颜色
  72.     QColor southPointerColor;       //南方指针颜色

  73.     QColor centerColorStart;        //中心圆渐变开始颜色
  74.     QColor centerColorEnd;          //中心圆渐变结束颜色

  75.     bool reverse;                   //是否倒退
  76.     double currentValue;            //当前值
  77.     QTimer *timer;                  //定时器绘制动画

  78. private slots:
  79.         void updateValue();

  80. public:
  81.         double getValue()               const;
  82.         int getPrecision()              const;

  83.         bool getAnimation()             const;
  84.         double getAnimationStep()       const;

  85.         QColor getCrownColorStart()     const;
  86.         QColor getCrownColorEnd()       const;

  87.         QColor getBgColorStart()        const;
  88.         QColor getBgColorEnd()          const;

  89.         QColor getDarkColor()           const;
  90.         QColor getLightColor()          const;

  91.         QColor getForeground()          const;
  92.         QColor getTextColor()           const;

  93.         QColor getNorthPointerColor()   const;
  94.         QColor getSouthPointerColor()   const;

  95.         QColor getCenterColorStart()    const;
  96.         QColor getCenterColorEnd()      const;

  97.         QSize sizeHint()                const;
  98.         QSize minimumSizeHint()         const;

  99. public Q_SLOTS:
  100.         //设置目标值
  101.         void setValue(double value);
  102.         void setValue(int value);

  103.         //设置精确度
  104.         void setPrecision(int precision);

  105.         //设置是否启用动画显示
  106.         void setAnimation(bool animation);
  107.         //设置动画显示的步长
  108.         void setAnimationStep(double animationStep);

  109.         //设置外边框渐变颜色
  110.     void setCrownColorStart(const QColor &crownColorStart);
  111.     void setCrownColorEnd(const QColor &crownColorEnd);

  112.         //设置背景渐变颜色
  113.     void setBgColorStart(const QColor &bgColorStart);
  114.     void setBgColorEnd(const QColor &bgColorEnd);

  115.         //设置加深和明亮颜色
  116.     void setDarkColor(const QColor &darkColor);
  117.     void setLightColor(const QColor &lightColor);

  118.         //设置前景色
  119.     void setForeground(const QColor &foreground);
  120.         //设置文本颜色
  121.     void setTextColor(const QColor &textColor);

  122.         //设置指针颜色
  123.     void setNorthPointerColor(const QColor &northPointerColor);
  124.     void setSouthPointerColor(const QColor &southPointerColor);

  125.         //设置中心圆颜色
  126.     void setCenterColorStart(const QColor ¢erColorStart);
  127.     void setCenterColorEnd(const QColor ¢erColorEnd);

  128. Q_SIGNALS:
  129.     void valueChanged(int value);
  130. };

  131. #endif // GAUGECOMPASS_H
复制代码
核心代码

  1. void GaugeCompass::paintEvent(QPaintEvent *)
  2. {
  3.     int width = this->width();
  4.     int height = this->height();
  5.     int side = qMin(width, height);

  6.     //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
  7.     QPainter painter(this);
  8.     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
  9.     painter.translate(width / 2, height / 2);
  10.     painter.scale(side / 200.0, side / 200.0);

  11.     //绘制外边框圆
  12.     drawCrownCircle(&painter);
  13.     //绘制背景圆
  14.     drawBgCircle(&painter);
  15.     //绘制刻度
  16.     drawScale(&painter);
  17.     //绘制东南西北标识
  18.     drawScaleNum(&painter);
  19.     //绘制覆盖圆外圆
  20.     drawCoverOuterCircle(&painter);
  21.     //绘制覆盖圆内圆
  22.     drawCoverInnerCircle(&painter);
  23.     //绘制覆盖圆中心圆
  24.     drawCoverCenterCircle(&painter);
  25.     //绘制南北指针
  26.     drawPointer(&painter);
  27.     //绘制中心圆
  28.     drawCenterCircle(&painter);
  29.     //绘制当前值
  30.     drawValue(&painter);
  31. }

  32. void GaugeCompass::drawCrownCircle(QPainter *painter)
  33. {
  34.     int radius = 99;
  35.     painter->save();
  36.     painter->setPen(Qt::NoPen);
  37.     QLinearGradient lineGradient(0, -radius, 0, radius);
  38.     lineGradient.setColorAt(0, crownColorStart);
  39.     lineGradient.setColorAt(1, crownColorEnd);
  40.     painter->setBrush(lineGradient);
  41.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  42.     painter->restore();
  43. }

  44. void GaugeCompass::drawBgCircle(QPainter *painter)
  45. {
  46.     int radius = 90;
  47.     painter->save();
  48.     painter->setPen(Qt::NoPen);
  49.     QLinearGradient lineGradient(0, -radius, 0, radius);
  50.     lineGradient.setColorAt(0, bgColorStart);
  51.     lineGradient.setColorAt(1, bgColorEnd);
  52.     painter->setBrush(lineGradient);
  53.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  54.     painter->restore();
  55. }

  56. void GaugeCompass::drawScale(QPainter *painter)
  57. {
  58.     int radius = 85;
  59.     painter->save();

  60.     //总共8格,4格为NESW字母,4格为线条
  61.     int steps = 8;
  62.     double angleStep = 360.0 / steps;

  63.     QPen pen;
  64.     pen.setColor(foreground);
  65.     pen.setCapStyle(Qt::RoundCap);
  66.     pen.setWidth(4);   
  67.     painter->setPen(pen);

  68.     //%2整数部分绘制NESW字母,其余绘制线条刻度
  69.     for (int i = 0; i <= steps; i++) {
  70.         if (i % 2 != 0) {
  71.             painter->drawLine(0, radius - 10, 0, radius);
  72.         }

  73.         painter->rotate(angleStep);
  74.     }

  75.     painter->restore();
  76. }

  77. void GaugeCompass::drawScaleNum(QPainter *painter)
  78. {
  79.     int radius = 88;
  80.     painter->save();
  81.     painter->setPen(foreground);

  82.     QFont font;
  83.     font.setPixelSize(15);
  84.     font.setBold(true);
  85.     painter->setFont(font);

  86.     QRect textRect = QRect(-radius, -radius, radius * 2, radius * 2);
  87.     painter->drawText(textRect, Qt::AlignTop | Qt::AlignHCenter, "N");
  88.     painter->drawText(textRect, Qt::AlignBottom | Qt::AlignHCenter, "S");

  89.     radius -= 2;
  90.     textRect = QRect(-radius, -radius, radius * 2, radius * 2);
  91.     painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, "W");

  92.     radius -= 2;
  93.     textRect = QRect(-radius, -radius, radius * 2, radius * 2);
  94.     painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, "E");

  95.     painter->restore();
  96. }

  97. void GaugeCompass::drawCoverOuterCircle(QPainter *painter)
  98. {
  99.     int radius = 68;
  100.     painter->save();
  101.     painter->setPen(Qt::NoPen);
  102.     QLinearGradient lineGradient(0, -radius, 0, radius);
  103.     lineGradient.setColorAt(0, lightColor);
  104.     lineGradient.setColorAt(1, darkColor);
  105.     painter->setBrush(lineGradient);
  106.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  107.     painter->restore();
  108. }

  109. void GaugeCompass::drawCoverInnerCircle(QPainter *painter)
  110. {
  111.     int radius = 60;
  112.     painter->save();
  113.     painter->setPen(Qt::NoPen);
  114.     QLinearGradient lineGradient(0, -radius, 0, radius);
  115.     lineGradient.setColorAt(0, darkColor);
  116.     lineGradient.setColorAt(1, lightColor);
  117.     painter->setBrush(lineGradient);
  118.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  119.     painter->restore();
  120. }

  121. void GaugeCompass::drawCoverCenterCircle(QPainter *painter)
  122. {
  123.     int radius = 15;
  124.     painter->save();
  125.     painter->setPen(Qt::NoPen);
  126.     painter->setOpacity(0.8);
  127.     QLinearGradient lineGradient(0, -radius, 0, radius);
  128.     lineGradient.setColorAt(0, lightColor);
  129.     lineGradient.setColorAt(1, darkColor);
  130.     painter->setBrush(lineGradient);
  131.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  132.     painter->restore();
  133. }

  134. void GaugeCompass::drawPointer(QPainter *painter)
  135. {
  136.     int radius = 75;

  137.     QPolygon pts;

  138.     painter->save();
  139.     painter->setOpacity(0.7);
  140.     painter->setPen(Qt::NoPen);
  141.     painter->setBrush(northPointerColor);
  142.     pts.setPoints(3, -10, 0, 10, 0, 0, radius);
  143.     painter->rotate(currentValue + 180);
  144.     painter->drawConvexPolygon(pts);
  145.     painter->restore();

  146.     painter->save();
  147.     painter->setOpacity(0.7);
  148.     painter->setPen(Qt::NoPen);
  149.     painter->setBrush(southPointerColor);
  150.     pts.setPoints(3, -10, 0, 10, 0, 0, radius);
  151.     painter->rotate(currentValue);
  152.     painter->drawConvexPolygon(pts);
  153.     painter->restore();
  154. }

  155. void GaugeCompass::drawCenterCircle(QPainter *painter)
  156. {
  157.     int radius = 12;
  158.     painter->save();
  159.     painter->setOpacity(1.0);
  160.     painter->setPen(Qt::NoPen);
  161.     QLinearGradient lineGradient(0, -radius, 0, radius);
  162.     lineGradient.setColorAt(0, centerColorStart);
  163.     lineGradient.setColorAt(1, centerColorEnd);
  164.     painter->setBrush(lineGradient);
  165.     painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  166.     painter->restore();
  167. }

  168. void GaugeCompass::drawValue(QPainter *painter)
  169. {
  170.     int radius = 100;
  171.     painter->save();
  172.     painter->setPen(textColor);

  173.     QFont font;
  174.     font.setPixelSize(11);
  175.     font.setBold(true);
  176.     painter->setFont(font);

  177.     QRectF textRect(-radius, -radius, radius * 2, radius * 2);
  178.     QString strValue = QString("%1").arg((double)value, 0, 'f', precision);
  179.     painter->drawText(textRect, Qt::AlignCenter, strValue);
  180.     painter->restore();
  181. }
复制代码


控件介绍

1. 超过130个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,不乱码,可直接集成到Qt  Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
6. 每个控件默认配色和demo对应的配色都非常精美。
7. 超过120个可见控件,6个不可见控件。
8. 部分控件提供多种样式风格选择,多种指示器样式选择。
9. 所有控件自适应窗体拉伸变化。
10.  集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。

SDK下载
- SDK下载链接:https://pan.baidu.com/s/1tD9v1YPfE2fgYoK6lqUr1Q 提取码:lyhk
- 自定义控件欣赏:https://pan.baidu.com/s/14iIecP4QLpYvreM1ZDN-dA 提取码:6rj4
- 属性设计器欣赏:https://pan.baidu.com/s/165aJuS_ukR6VGugbtGaf4g 提取码:6014
- 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo。
- 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
- widget版本(QQ:517216493)qml版本(QQ:373955953)三峰驼(QQ:278969898)。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:1 天
连续签到:1 天
2019-5-26 20:02:04 显示全部楼层
真不错,像大牛致敬!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了