qt 仪表自定义控件

请添加图片描述

源码
圆弧上的点,对应的坐标计算方式。
x1 = x0 + r * cos(angle * 3.14 /180 )
y1 = y0 + r * sin(angle * 3.14 /180 )
x0 y0 —>中心点 angle 角度

qwidget(paintevent事件实现)废话不多说实现逻辑如下:

void UMeter::paintEvent(QPaintEvent *event)
{

    int radius = 100;
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);
    p.translate(width() / 2, height() / 2);
#if 1
    int anglevalue = 0;
    QPen pen;
    pen.setColor(QColor("#646464A0"));
    pen.setWidth(4);
    p.setPen(pen);
    p.drawEllipse(QPoint(0,0),radius+4,radius+4);
    p.setPen(QColor("#636363"));
    p.drawEllipse(QPoint(0,0),radius+5,radius+5);

    p.setPen(QColor("#636363"));
    p.setBrush(Qt::black);
    p.drawEllipse(QPoint(0,0),radius,radius);

    p.setPen(QColor("#636363"));
    setLinearGradientColor(p,QColor("#FF005600"),QColor("#FF005600"),QColor("#00005600"),QPointF(0,-radius),QPointF(0,radius));
    p.drawEllipse(QPoint(0,0),radius,radius);

    p.setPen(Qt::red);
    for (int i = 0; i < BigScale; ++i) {
        if (anglevalue < 60 || anglevalue > 120)
        {
            p.drawLine(85,0,radius,0);
        }
        double angle = 360.00/BigScale;
        p.rotate(angle);
        anglevalue = anglevalue + angle;
    }

    anglevalue = 0;
    p.setPen(Qt::yellow);
    for (int i = 0; i < ModleScale; ++i) {
        if (anglevalue <= 60 || anglevalue >= 120)
        {
            if (i % 3 != 0)
                p.drawLine(90,0,radius,0);
        }
        double angle = 360.00/ModleScale;
        p.rotate(angle);
        anglevalue = anglevalue + angle;
    }

    anglevalue = 0;
    p.setPen(Qt::white);
    for (int i = 0; i < SmallScale; ++i) {
        if (anglevalue < 60 || anglevalue > 120)
        {
            if (i % 5 != 0)
                p.drawLine(95,0,radius,0);
        }
        double angle = 360.00/SmallScale;
        p.rotate(angle);
        anglevalue = anglevalue + angle;
    }

    anglevalue = 0;
    p.setPen(Qt::white);
    QStringList list;
    list<<"180"<<"210"<<"240"<<"270"<<"300"<<"330"<<"360"<<"30"<<"60"<<"90"<<"120"<<"150";
    for (int i = 0; i < ModleScale; ++i) {
        if (anglevalue >= 210 || anglevalue <= 150)
        {
            p.drawText(QRect(-8,-85,16,16),Qt::AlignHCenter,list[i]);
        }
        double angle = 360.00/ModleScale;
        p.rotate(angle);
        anglevalue = anglevalue + angle;
    }

    p.save();
    pen.setColor(Qt::gray);
    p.setPen(pen);
    QPoint points[3];
    points[0] = QPoint(-3,0);
    points[1] = QPoint(3,0);
    points[2] = QPoint(0,radius);
    if (m_xangle < 30)
        m_xangle = 330;
    else if(m_xangle>330)
        m_xangle = 30;
    p.rotate(m_xangle);
    p.drawConvexPolygon(points,3);
    p.restore();

    QString val = QString("%1km/h").arg(m_xangle);
    pen.setColor(Qt::white);
    p.setPen(pen);
    p.setFont(QFont("微软雅黑",12,QFont::Bold,false));
    p.drawText(-50,40,radius,40,Qt::AlignHCenter,val);

    //圆弧
    setConicalGradientColor(p,QColor("#FFFF0000"),QColor("#7DFF0000"),QColor("#FF005600"),QColor("#007D5600"),QPoint(0,0),245);
    QRect arcRect = QRect(-radius-10,-radius-10,2*(radius+10),2*(radius+10));
    double startAngle = 240 * 16;
    double spanAngle = -(m_xangle - 30) * 16;
    p.drawArc(arcRect,startAngle,spanAngle);

    //文字底盘
    p.setBrush(Qt::NoBrush);
    pen.setColor("#3074c6");
    pen.setWidth(20);
    p.setPen(pen);
    p.drawEllipse(QPoint(0,0),radius+30,radius+30);
    p.setBrush(Qt::NoBrush);
    p.setPen(Qt::black);
    p.drawEllipse(QPoint(0,0),radius+20,radius+20);
    p.drawEllipse(QPoint(0,0),radius+40,radius+40);
#endif
    //跑马灯圆弧
    QConicalGradient conicalGradient(QPoint(0,0),-m_xangle);
    conicalGradient.setColorAt(0,QColor("#81aff3"));
    conicalGradient.setColorAt(0.60,QColor("#FFFFFF"));
    conicalGradient.setColorAt(0.63,QColor("#FFFFFF"));
    conicalGradient.setColorAt(1,QColor("#81aff3"));
    conicalGradient.setSpread(QGradient::PadSpread);
    pen = QPen(QBrush(conicalGradient),5);
    p.setPen(pen);
    QRect lightarcRect = QRect(-radius-30,-radius-30,2*(radius+30),2*(radius+30));
    startAngle = (240-m_xangle+45) * 16;
    spanAngle = -30 * 16;
    p.drawArc(lightarcRect,startAngle,spanAngle);

    //文字
    p.setPen(Qt::black);
    int font_size = 16;
    // 设置字符间距
    QFont font;
    font.setFamily("Microsoft YaHei");
    // 大小
    font.setPointSize(font_size);
    // 使用字体
    p.setFont(font);

    //圆弧上的点,对应的坐标计算方式。
    //x1 = x0 + r * cos(angle * 3.14 /180 )
    //y1 = y0 + r * sin(angle * 3.14 /180 )
    //x0 y0 —>中心点 angle 角度
#if 0
    static QString m_string("12345678");
    for(int i=0; i<m_string.count(); i++)
    {
        // 按正弦函数绘制
        int ang = -180/(m_string.count()-1)*i;
        float tx = -7.5-(radius+30)*cos(ang*(3.14/180));
        float ty = (radius+20)*sin(ang*(3.14/180));
//        qDebug()<<tx<<ang<<ty;
        //压缩y坐标
        p.drawText(QPointF(tx, ty), QString("%1").arg(m_string[i]));
    }
#else
    QString str1("正常模式");
    p.setPen(Qt::green);
    for(int i=0; i<str1.count(); i++)
    {
        // 按正弦函数绘制
        int bAngle = 60;
        int ang = -bAngle/(str1.count()-1)*i;
        float tx = -10-(radius+30)*cos(ang*(PI/180));
        float ty = (radius+20)*sin(ang*(PI/180));
        //压缩y坐标
        p.drawText(QPointF(tx, ty), QString("%1").arg(str1[i]));
    }
    QString str2("        高温模式");
    p.setPen(Qt::red);
    for(int i=0; i<str2.count(); i++)
    {
        // 按正弦函数绘制
        int bAngle = 180;
        int ang = -bAngle/(str2.count()-1)*i;
        float tx = -10-(radius+30)*cos(ang*(PI/180));
        float ty = (radius+20)*sin(ang*(PI/180));
        //压缩y坐标
        p.drawText(QPointF(tx, ty), QString("%1").arg(str2[i]));
    }
#endif
}

void UMeter::setConicalGradientColor(QPainter &p, QColor a,QColor b,QColor c,QColor d,const QPointF &center, qreal startAngle)
{
    QConicalGradient conicalGradient(center,startAngle);
    conicalGradient.setColorAt(0,a);
    conicalGradient.setColorAt(0.5,b);
    conicalGradient.setColorAt(0.75,c);
    conicalGradient.setColorAt(1,d);
    conicalGradient.setSpread(QGradient::PadSpread);
    QPen pen = QPen(QBrush(conicalGradient),15);
    p.setPen(pen);
}

void UMeter::setLinearGradientColor(QPainter &p, QColor a,QColor b,QColor c,const QPointF &start, const QPointF &finalStop)
{
    QLinearGradient lineargradient(start,finalStop);
    lineargradient.setColorAt(0,a);
    lineargradient.setColorAt(0.5,b);
    lineargradient.setColorAt(1,c);
    lineargradient.setSpread(QGradient::PadSpread);
    QBrush brush = QBrush(lineargradient);
    p.setBrush(brush);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值