目录
  • 1.预览图
  • 2. 代码
    • 头文件
    • 源文件
  • 3. 用法

    1.预览图

    Qt自定义控件实现仪表盘

    2. 代码

    头文件

    #ifndef MOTORMETER_H
    #define MOTORMETER_H
    
    #include <QWidget>
    #include <QDebug>
    #include <QtMath>
    #include <QDialog>
    #include <QPainter>
    #include <QPaintEvent>
    #include <QPainterPath>
    #include <QRadialGradient>
    
    class motormeter : public QWidget
    {
        Q_OBJECT
    public:
        explicit motormeter(QWidget *parent = nullptr);
        ~motormeter();
    protected:
        void paintEvent(QPaintEvent*);
    private:
        int degRotate =-120;
    
    private:
        void DrawPoint(QPainter&,int);
        void DrawDigital(QPainter&,int);
        void DrawCircle(QPainter&,int);
        void DrawSmallScale(QPainter&,int);
        void DrawBigScale(QPainter&,int);
        void DrawText(QPainter&,int);
        void DrawPointer(QPainter&,int);
        void drawIndicator(QPainter *painter);
    
    public slots:
        void valueChanged(int);
    };
    
    #endif // MOTORMETER_H
    

    源文件

    #include "motormeter.h"
    
    motormeter::motormeter(QWidget *parent) : QWidget(parent)
    {
    }
    
    motormeter::~motormeter()
    {
    
    }
    
    void motormeter::paintEvent(QPaintEvent*)
    {
    
        QPainter painter(this);
        int width=this->width();
        int height=this->height();
        int radius=((width>height)?height:width)/2;
        //移动画笔到中下方
        painter.translate(width/2,height*0.6);
        //启用反锯齿
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(Qt::NoPen);
        //设置画刷颜色
        painter.setBrush(QColor(138,43,226));
        DrawPoint(painter,radius);
        DrawDigital(painter,radius-10);
        DrawCircle(painter,radius-35);
        DrawSmallScale(painter,radius-60);
        DrawBigScale(painter,radius-75);
        DrawText(painter,radius/2);
        DrawPointer(painter,radius-100);
    
    }
    //绘制外圈点
    void motormeter::DrawPoint(QPainter& painter,int radius)
    {
        //组装点的路径图
        QPainterPath pointPath;
        pointPath.moveTo(-2,-2);
        pointPath.lineTo(2,-2);
        pointPath.lineTo(2,2);
        pointPath.lineTo(0,4);
        pointPath.lineTo(-2,2);
        //绘制13个小点
        for(int i=0;i<13;++i){
            QPointF point(0,0);
            painter.save();
            painter.setBrush(QColor(255,127,80));
            //计算并移动绘图对象中心点
            point.setX(radius*qCos(((210-i*20)*M_PI)/180));
            point.setY(radius*qSin(((210-i*20)*M_PI)/180));
            //计算并移动绘图对象的中心点
            painter.translate(point.x(),-point.y());
            //计算并选择绘图对象坐标
            painter.rotate(-120+i*20);
            //绘制路径
            painter.drawPath(pointPath);
            painter.restore();
        }
    }
    //绘制外圈数字,原理和绘制圆圈点一样
    void motormeter::DrawDigital(QPainter& painter,int radius)
    {
        //设置画笔,画笔默认NOPEN
        painter.setPen(QColor(218,112,214));
        QFont font;
        font.setFamily("Cambria");
        font.setPointSize(15);
        painter.setFont(font);
        for(int i=0;i<13;++i){
            QPointF point(0,0);
            painter.save();
            point.setX(radius*qCos(((210-i*20)*M_PI)/180));
            point.setY(radius*qSin(((210-i*20)*M_PI)/180));
            painter.translate(point.x(),-point.y());
            painter.rotate(-120+i*20);
            painter.drawText(-15, -5, 40, 30,Qt::AlignCenter,QString::number(i*20));
            painter.restore();
        }
        //还原画笔
        painter.setPen(Qt::NoPen);
    }
    //绘制外圈
    void motormeter::DrawCircle(QPainter& painter,int radius)
    {
        //保存绘图对象
        painter.save();
        //计算大小圆路径
        QPainterPath outRing;
        QPainterPath inRing;
        outRing.moveTo(0,0);
        inRing.moveTo(0,0);
        outRing.arcTo(-radius,-radius, 2*radius,2*radius,-31,242);
        inRing.addEllipse(-radius+20,-radius+20,2*(radius-20),2*(radius-20));
        outRing.closeSubpath();
        //设置渐变色k
        QRadialGradient radialGradient(0,0,radius,0,0);
        radialGradient.setColorAt(0.93,QColor(138,43,226));
        radialGradient.setColorAt(1,QColor(0,0,0));
        //设置画刷
        painter.setBrush(radialGradient);
        //大圆减小圆
        painter.drawPath(outRing.subtracted(inRing));
        //painter.drawPath(outRing);
        //painter.drawPath(inRing);
        painter.restore();
    }
    //绘制刻度
    void motormeter::DrawSmallScale(QPainter& painter,int radius)
    {
        //组装点的路径图
        QPainterPath pointPath;
        pointPath.moveTo(-2,-2);
        pointPath.lineTo(-1,-4);
        pointPath.lineTo(1,-4);
        pointPath.lineTo(2,-2);
        pointPath.lineTo(1,8);
        pointPath.lineTo(-1,8);
        //绘制121个小点
        for(int i=0;i<121;++i){
            QPointF point(0,0);
            painter.save();
            point.setX(radius*qCos(((210-i*2)*M_PI)/180));
            point.setY(radius*qSin(((210-i*2)*M_PI)/180));
            painter.translate(point.x(),-point.y());
            painter.rotate(-120+i*2);
            if(i>=90) painter.setBrush(QColor(250,0,0));
            painter.drawPath(pointPath);
            painter.restore();
        }
    }
    //绘制刻度
    void motormeter::DrawBigScale(QPainter& painter,int radius)
    {
        //组装点的路径图
        QPainterPath pointPath1;
        pointPath1.moveTo(-2,-2);
        pointPath1.lineTo(-1,-4);
        pointPath1.lineTo(1,-4);
        pointPath1.lineTo(2,-2);
        pointPath1.lineTo(1,8);
        pointPath1.lineTo(-1,8);
        QPainterPath pointPath2;
        pointPath2.moveTo(-2,-2);
        pointPath2.lineTo(-1,-4);
        pointPath2.lineTo(1,-4);
        pointPath2.lineTo(2,-2);
        pointPath2.lineTo(1,15);
        pointPath2.lineTo(-1,15);
        //绘制25个刻度
        for(int i=0;i<25;++i){
            QPointF point(0,0);
            painter.save();
            point.setX(radius*qCos(((210-i*10)*M_PI)/180));
            point.setY(radius*qSin(((210-i*10)*M_PI)/180));
            painter.translate(point.x(),-point.y());
            painter.rotate(-120+i*10);
            if(i>=18) painter.setBrush(QColor(250,0,0));
            if(i%2){
                painter.drawPath(pointPath1);
            }
            else{
                painter.drawPath(pointPath2);
            }
            painter.restore();
        }
    }
    //绘制中心文字km/h
    void motormeter::DrawText(QPainter& painter,int radius)
    {
        painter.save();
        painter.setPen(QColor(153,51,250));
        QFont font;
        font.setFamily("Cambria");
        font.setPointSize(16);
        painter.setFont(font);
        painter.drawText(-25, -radius, 60, 30,Qt::AlignCenter,QString("km/h"));
        painter.restore();
    }
    //绘制指针
    void motormeter::DrawPointer(QPainter& painter,int radius)
    {
        //组装点的路径图
        QPainterPath pointPath;
        pointPath.moveTo(10,0);
        pointPath.lineTo(1,-radius);
        pointPath.lineTo(-1,-radius);
        pointPath.lineTo(-10,0);
        pointPath.arcTo(-10,0,20,20,180,180);
        QPainterPath inRing;
        inRing.addEllipse(-5,-5,10,10);
        painter.save();
        QRadialGradient radialGradient(0,0,radius,0,0);
        radialGradient.setColorAt(0,QColor(0,199,140,150));
        radialGradient.setColorAt(1,QColor(255,153,18,150));
        //计算并选择绘图对象坐标
        painter.rotate(degRotate);
        painter.setBrush(radialGradient);
        painter.drawPath(pointPath.subtracted(inRing));
        painter.restore();
    }
    void motormeter::valueChanged(int value)
    {
        this->degRotate = value;
        update();
    }

    3. 用法

    创建类,然后在创建的头文件和源文件里面添加上述代码

    Qt自定义控件实现仪表盘

    Qt自定义控件实现仪表盘

    在UI界面里面拖拽widget部件

    Qt自定义控件实现仪表盘

    将widget部件提升为自定义的类,在提升的类名称里面填入上面源代码里面的类名

    Qt自定义控件实现仪表盘

    调用函数如下,在设计师界面类里面调用这个函数即可

    void motormeter::valueChanged(int value)
    {
        this->degRotate = value;
        update();
    }
    
    //设置背景墙
    QPalette bgpal= palette();
    bgpal.setColor(QPalette::Background,QColor(0,0,0));
    setPalette (bgpal);
    ui->motormeter->valueChanged(a);

    以上就是Qt自定义控件实现仪表盘的详细内容,更多关于Qt仪表盘的资料请关注其它相关文章!

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。