zoukankan      html  css  js  c++  java
  • Qt编写自定义控件6-指南针仪表盘

    前言

    指南针仪表盘,主要用来指示东南西北四个方位,双向对称两个指针旋转,其实就是360度打转,功能属于简单型,可能指针的绘制稍微难一点,需要计算多个点构成多边形,本系列控件文章将会连续发100+篇,一方面为了锻炼自己的毅力+坚持力,一方面为了宣传自己,如果各位对完整的源码有兴趣可以私聊,也欢迎在文章下面评论提出建议,谢谢!

    实现的功能

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

    效果图

    头文件代码

    #ifndef GAUGECOMPASS_H
    #define GAUGECOMPASS_H
    
    /**
     * 指南针仪表盘控件 作者:feiyangqingyun(QQ:517216493) 2016-11-12
     * 1:可设置当前度数
     * 2:可设置精确度
     * 3:可设置是否启用动画及步长
     * 4:可设置边框渐变颜色
     * 5:可设置背景渐变颜色
     * 6:可设置加深和明亮颜色
     * 7:可设置指南指北指针颜色
     * 8:可设置中心点渐变颜色
     */
    
    #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 GaugeCompass : public QWidget
    #else
    class GaugeCompass : public QWidget
    #endif
    
    {
    	Q_OBJECT
    	Q_PROPERTY(double value READ getValue WRITE setValue)
    	Q_PROPERTY(int precision READ getPrecision WRITE setPrecision)
    
    	Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
    	Q_PROPERTY(double animationStep READ getAnimationStep WRITE setAnimationStep)
    
    	Q_PROPERTY(QColor crownColorStart READ getCrownColorStart WRITE setCrownColorStart)
    	Q_PROPERTY(QColor crownColorEnd READ getCrownColorEnd WRITE setCrownColorEnd)
    
    	Q_PROPERTY(QColor bgColorStart READ getBgColorStart WRITE setBgColorStart)
    	Q_PROPERTY(QColor bgColorEnd READ getBgColorEnd WRITE setBgColorEnd)
    
    	Q_PROPERTY(QColor darkColor READ getDarkColor WRITE setDarkColor)
    	Q_PROPERTY(QColor lightColor READ getLightColor WRITE setLightColor)
    
    	Q_PROPERTY(QColor foreground READ getForeground WRITE setForeground)
    	Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
    
    	Q_PROPERTY(QColor northPointerColor READ getNorthPointerColor WRITE setNorthPointerColor)
    	Q_PROPERTY(QColor southPointerColor READ getSouthPointerColor WRITE setSouthPointerColor)
    
    	Q_PROPERTY(QColor centerColorStart READ getCenterColorStart WRITE setCenterColorStart)
    	Q_PROPERTY(QColor centerColorEnd READ getCenterColorEnd WRITE setCenterColorEnd)
    
    public:
    	explicit GaugeCompass(QWidget *parent = 0);
        ~GaugeCompass();
    
    protected:
    	void paintEvent(QPaintEvent *);
    	void drawCrownCircle(QPainter *painter);
    	void drawBgCircle(QPainter *painter);
    	void drawScale(QPainter *painter);
    	void drawScaleNum(QPainter *painter);
    	void drawCoverOuterCircle(QPainter *painter);
    	void drawCoverInnerCircle(QPainter *painter);
    	void drawCoverCenterCircle(QPainter *painter);
    	void drawPointer(QPainter *painter);
    	void drawCenterCircle(QPainter *painter);
        void drawValue(QPainter *painter);
    
    private:
        double value;                   //目标值
        int precision;                  //精确度,小数点后几位
    
        bool animation;                 //是否启用动画显示
        double animationStep;           //动画显示时步长
    
        QColor crownColorStart;         //外边框渐变开始颜色
        QColor crownColorEnd;           //外边框渐变结束颜色
    
        QColor bgColorStart;            //背景渐变开始颜色
        QColor bgColorEnd;              //背景渐变结束颜色
    
        QColor darkColor;               //加深颜色
        QColor lightColor;              //明亮颜色
    
        QColor foreground;              //前景色
        QColor textColor;               //文字颜色
    
        QColor northPointerColor;       //北方指针颜色
        QColor southPointerColor;       //南方指针颜色
    
        QColor centerColorStart;        //中心圆渐变开始颜色
        QColor centerColorEnd;          //中心圆渐变结束颜色
    
        bool reverse;                   //是否倒退
        double currentValue;            //当前值
        QTimer *timer;                  //定时器绘制动画
    
    private slots:
    	void updateValue();
    
    public:
    	double getValue()               const;
    	int getPrecision()              const;
    
    	bool getAnimation()             const;
    	double getAnimationStep()       const;
    
    	QColor getCrownColorStart()     const;
    	QColor getCrownColorEnd()       const;
    
    	QColor getBgColorStart()        const;
    	QColor getBgColorEnd()          const;
    
    	QColor getDarkColor()           const;
    	QColor getLightColor()          const;
    
    	QColor getForeground()          const;
    	QColor getTextColor()           const;
    
    	QColor getNorthPointerColor()   const;
    	QColor getSouthPointerColor()   const;
    
    	QColor getCenterColorStart()    const;
    	QColor getCenterColorEnd()      const;
    
    	QSize sizeHint()                const;
    	QSize minimumSizeHint()         const;
    
    public Q_SLOTS:
    	//设置目标值
    	void setValue(double value);
    	void setValue(int value);
    
    	//设置精确度
    	void setPrecision(int precision);
    
    	//设置是否启用动画显示
    	void setAnimation(bool animation);
    	//设置动画显示的步长
    	void setAnimationStep(double animationStep);
    
    	//设置外边框渐变颜色
        void setCrownColorStart(const QColor &crownColorStart);
        void setCrownColorEnd(const QColor &crownColorEnd);
    
    	//设置背景渐变颜色
        void setBgColorStart(const QColor &bgColorStart);
        void setBgColorEnd(const QColor &bgColorEnd);
    
    	//设置加深和明亮颜色
        void setDarkColor(const QColor &darkColor);
        void setLightColor(const QColor &lightColor);
    
    	//设置前景色
        void setForeground(const QColor &foreground);
    	//设置文本颜色
        void setTextColor(const QColor &textColor);
    
    	//设置指针颜色
        void setNorthPointerColor(const QColor &northPointerColor);
        void setSouthPointerColor(const QColor &southPointerColor);
    
    	//设置中心圆颜色
        void setCenterColorStart(const QColor &centerColorStart);
        void setCenterColorEnd(const QColor &centerColorEnd);
    
    Q_SIGNALS:
        void valueChanged(int value);
    };
    
    #endif // GAUGECOMPASS_H
    
    

    核心代码

    void GaugeCompass::paintEvent(QPaintEvent *)
    {
        int width = this->width();
        int height = this->height();
        int side = qMin(width, height);
    
        //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
        QPainter painter(this);
        painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
        painter.translate(width / 2, height / 2);
        painter.scale(side / 200.0, side / 200.0);
    
        //绘制外边框圆
        drawCrownCircle(&painter);
        //绘制背景圆
        drawBgCircle(&painter);
        //绘制刻度
        drawScale(&painter);
        //绘制东南西北标识
        drawScaleNum(&painter);
        //绘制覆盖圆外圆
        drawCoverOuterCircle(&painter);
        //绘制覆盖圆内圆
        drawCoverInnerCircle(&painter);
        //绘制覆盖圆中心圆
        drawCoverCenterCircle(&painter);
        //绘制南北指针
        drawPointer(&painter);
        //绘制中心圆
        drawCenterCircle(&painter);
        //绘制当前值
        drawValue(&painter);
    }
    
    void GaugeCompass::drawCrownCircle(QPainter *painter)
    {
        int radius = 99;
        painter->save();
        painter->setPen(Qt::NoPen);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, crownColorStart);
        lineGradient.setColorAt(1, crownColorEnd);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawBgCircle(QPainter *painter)
    {
        int radius = 90;
        painter->save();
        painter->setPen(Qt::NoPen);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, bgColorStart);
        lineGradient.setColorAt(1, bgColorEnd);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawScale(QPainter *painter)
    {
        int radius = 85;
        painter->save();
    
        //总共8格,4格为NESW字母,4格为线条
        int steps = 8;
        double angleStep = 360.0 / steps;
    
        QPen pen;
        pen.setColor(foreground);
        pen.setCapStyle(Qt::RoundCap);
        pen.setWidth(4);    
        painter->setPen(pen);
    
        //%2整数部分绘制NESW字母,其余绘制线条刻度
        for (int i = 0; i <= steps; i++) {
            if (i % 2 != 0) {
                painter->drawLine(0, radius - 10, 0, radius);
            }
    
            painter->rotate(angleStep);
        }
    
        painter->restore();
    }
    
    void GaugeCompass::drawScaleNum(QPainter *painter)
    {
        int radius = 88;
        painter->save();
        painter->setPen(foreground);
    
        QFont font;
        font.setPixelSize(15);
        font.setBold(true);
        painter->setFont(font);
    
        QRect textRect = QRect(-radius, -radius, radius * 2, radius * 2);
        painter->drawText(textRect, Qt::AlignTop | Qt::AlignHCenter, "N");
        painter->drawText(textRect, Qt::AlignBottom | Qt::AlignHCenter, "S");
    
        radius -= 2;
        textRect = QRect(-radius, -radius, radius * 2, radius * 2);
        painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, "W");
    
        radius -= 2;
        textRect = QRect(-radius, -radius, radius * 2, radius * 2);
        painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, "E");
    
        painter->restore();
    }
    
    void GaugeCompass::drawCoverOuterCircle(QPainter *painter)
    {
        int radius = 68;
        painter->save();
        painter->setPen(Qt::NoPen);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, lightColor);
        lineGradient.setColorAt(1, darkColor);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawCoverInnerCircle(QPainter *painter)
    {
        int radius = 60;
        painter->save();
        painter->setPen(Qt::NoPen);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, darkColor);
        lineGradient.setColorAt(1, lightColor);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawCoverCenterCircle(QPainter *painter)
    {
        int radius = 15;
        painter->save();
        painter->setPen(Qt::NoPen);
        painter->setOpacity(0.8);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, lightColor);
        lineGradient.setColorAt(1, darkColor);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawPointer(QPainter *painter)
    {
        int radius = 75;
    
        QPolygon pts;
    
        painter->save();
        painter->setOpacity(0.7);
        painter->setPen(Qt::NoPen);
        painter->setBrush(northPointerColor);
        pts.setPoints(3, -10, 0, 10, 0, 0, radius);
        painter->rotate(currentValue + 180);
        painter->drawConvexPolygon(pts);
        painter->restore();
    
        painter->save();
        painter->setOpacity(0.7);
        painter->setPen(Qt::NoPen);
        painter->setBrush(southPointerColor);
        pts.setPoints(3, -10, 0, 10, 0, 0, radius);
        painter->rotate(currentValue);
        painter->drawConvexPolygon(pts);
        painter->restore();
    }
    
    void GaugeCompass::drawCenterCircle(QPainter *painter)
    {
        int radius = 12;
        painter->save();
        painter->setOpacity(1.0);
        painter->setPen(Qt::NoPen);
        QLinearGradient lineGradient(0, -radius, 0, radius);
        lineGradient.setColorAt(0, centerColorStart);
        lineGradient.setColorAt(1, centerColorEnd);
        painter->setBrush(lineGradient);
        painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
        painter->restore();
    }
    
    void GaugeCompass::drawValue(QPainter *painter)
    {
        int radius = 100;
        painter->save();
        painter->setPen(textColor);
    
        QFont font;
        font.setPixelSize(11);
        font.setBold(true);
        painter->setFont(font);
    
        QRectF textRect(-radius, -radius, radius * 2, radius * 2);
        QString strValue = QString("%1").arg((double)value, 0, 'f', precision);
        painter->drawText(textRect, Qt::AlignCenter, strValue);
        painter->restore();
    }
    
    

    控件介绍

    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下载


  • 相关阅读:
    arcgis10.4.X的oracle数据库要求
    面试高峰期,如何应对面试官的jvm刁难,特写一篇jvm面经(第一部)
    某公司面试打分文档,75分通过
    git-github 提示Permission denied (publickey) (windows)
    jar项目 BeanDefinitionParsingException: Configuration problem:Unable to locate Spring NamespaceHandler for XML schema namespace
    关于No Spring WebApplicationInitializer types detected on classpath的提示,tomcat 卡主
    spring+orm框架的兼容问题
    程序员常用工具
    IDEA-常见问题
    IDEA-基本设置
  • 原文地址:https://www.cnblogs.com/feiyangqingyun/p/10759607.html
Copyright © 2011-2022 走看看