漂亮的表盘(自绘)

先看效果
这里写图片描述

这次用了二种方式实现的。一种是利用QPainter直接绘制的,一种是利用QPainterPath实现的。
头文件代码

#ifndef QDIALCOMPWIDGET_H
#define QDIALCOMPWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QConicalGradient>
#include "qmath.h"

#define  PI 3.12415926

//////////////////////////////////////////////////////////////////////////
//不支持指针颜色动态变化
//////////////////////////////////////////////////////////////////////////
class QDialCompWidget : public QWidget
{
    Q_OBJECT

public:
    QDialCompWidget(QWidget *parent = NULL);
    ~QDialCompWidget();

    void setMaxValue(qreal max);
    void setMinValue(qreal min);
    void setValue(qreal value);
    void setSuffix(QString sufstr); //后缀

private:
    inline void initdata();

protected:
    void paintEvent(QPaintEvent *e);
    void drawRoundByPath(QPainter &painter);    //利用QPainterPath 实现
    void drawRoundByPainter(QPainter &painter); //利用QPainter实现

private:
    QString m_sufstr;
    qreal m_max;
    qreal m_min;
    qreal m_value;
    QBrush m_oldbrush;


};

#endif // QDIALCOMPWIDGET_H

Cpp文件代码

#include "qdialcompwidget.h"

QDialCompWidget::QDialCompWidget(QWidget *parent)
    : QWidget(parent)
{
    initdata();
}

QDialCompWidget::~QDialCompWidget()
{

}

void QDialCompWidget::initdata()
{
    m_max = 100;
    m_min = 0;
    m_value = 0;
}
void QDialCompWidget::setMaxValue( qreal max )
{
    m_max = max;
    update();
}

void QDialCompWidget::setMinValue( qreal min )
{
    m_min = min;
    update();
}

void QDialCompWidget::setValue( qreal value )
{
    m_value = value;
    update();

}

void QDialCompWidget::setSuffix( QString sufstr )
{
    m_sufstr = sufstr;
    update();
}

void QDialCompWidget::paintEvent( QPaintEvent *e )
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    m_oldbrush = painter.background();
    //drawRoundByPainter(painter);
    drawRoundByPath(painter);
}

void QDialCompWidget::drawRoundByPainter( QPainter &painter )
{
    int w = width();
    int h = height();
    qreal randius= qMin(w*0.8/2,h*0.8/2);
    int setp = randius*0.08;
    qreal outrandius = randius + setp;
    qreal inrandius = randius - setp;

    QPointF certp(w/2,h/2);
    qreal startAngle = -60*16;
    qreal spanAngle = 300*16;
    qreal angele = 30;
    qreal lw,lh;
    lw = outrandius*qSin(PI/6);
    lh = outrandius*qCos(PI/6);

    QPointF outleftp(certp.x()-lw,certp.y()+lh);
    QPointF outrigth(certp.x()+lw,certp.y()+lh);
    QRectF outrectangle(certp.x()-outrandius, certp.y()-outrandius, outrandius*2, outrandius*2);

    //背景色
    painter.save();
    painter.setBrush(m_oldbrush);
    painter.drawEllipse(outrectangle);
    painter.restore();

    //外圆
    painter.save();
    QConicalGradient congradient(outrectangle.center(),245);
    congradient.setColorAt(0,QColor("#EC0000")); //红色
    congradient.setColorAt(0.5,QColor("#E5D317"));
    congradient.setColorAt(1,QColor("#2BB52C"));   //绿色
    painter.setBrush(congradient);
    painter.drawPie(outrectangle, startAngle, spanAngle);
    painter.restore();


    //内圆
    lw = inrandius*qSin(PI/6);
    lh = inrandius*qCos(PI/6);

    QPointF inleftp(certp.x()-lw,certp.y()+lh);
    QPointF inrigth(certp.x()+lw,certp.y()+lh);

    painter.save();
    QRectF inrectangle(certp.x()-inrandius, certp.y()-inrandius, inrandius*2, inrandius*2);
    painter.drawPie(inrectangle,startAngle,spanAngle);
    painter.restore();

    painter.save();
    painter.setBrush(congradient);
    //左侧半小圆
    qreal tmph =(outleftp.y()-inleftp.y())/2;
    qreal tmpw =(outleftp.x()-inleftp.x())/2;

    QPointF tp(outleftp.x()-tmpw,outleftp.y()-tmph);
    QRectF rmprect(tp.x()-setp,tp.y()-setp,setp*2,setp*2);
    painter.drawChord(rmprect,-130*16,200*16);  //角度大小取决于 angele ,跨度200级以上(防止放大有小白条)

    //右侧半小圆
    tmph =(outrigth.y()-inrigth.y())/2;
    tmpw =(outrigth.x()-inrigth.x())/2;

    QPointF righttp(outrigth.x()-tmpw,outrigth.y()-tmph);
    QRectF rmrightrect(righttp.x()-setp,righttp.y()-setp,setp*2,setp*2);
    painter.drawChord(rmrightrect,110*16,200*16); //角度大小取决于 angele,跨度200级以上(防止放大有小白条)
    painter.restore();

    //中间部分 白色填充
    painter.save();
    painter.setBrush(/*Qt::white*/m_oldbrush);
    painter.drawEllipse(inrectangle);
    painter.restore();

    //里侧圆
    painter.save();
    qreal inirandius = inrandius*0.9;
    QPainterPath path;
    QRectF inirect(certp.x()-inirandius,certp.y()-inirandius,inirandius*2,inirandius*2);

    QRadialGradient radialgradient(inirect.center(),inirandius);
    QColor color_1("#2BB52C"); //绿色
    QColor color_2("#2BB52C");
    QColor color_3("#2BB52C");
    color_1.setAlpha(200);
    color_2.setAlpha(100);
    color_3.setAlpha(20);
    radialgradient.setColorAt(0.95,color_1); //
    radialgradient.setColorAt(0.99,color_2);
    radialgradient.setColorAt(1,color_3);   
    painter.setBrush(radialgradient);

    path.addEllipse(inirect);

    painter.drawPath(path);
    painter.restore();
    painter.save();
    painter.setBrush(/*Qt::white*/m_oldbrush);
    inirandius *= 0.97;
    QRectF tmprect(certp.x()-inirandius,certp.y()-inirandius,inirandius*2,inirandius*2);
    painter.drawEllipse(tmprect);
    painter.restore();

    //值value
    painter.save();
    QPen textpen;
    textpen.setColor("black");
    QFont f;
    f.setPixelSize(inirandius/2);
    painter.setPen(textpen);
    painter.setFont(f);
    painter.drawText(tmprect,Qt::AlignCenter,QString("%1%2").arg(m_value).arg(m_sufstr));
    painter.restore();

    //最大最小值
    painter.save();
    QFont f2;
    f2.setPixelSize(inirandius/4);
    painter.setPen(textpen);
    painter.setFont(f2);
    QRectF minrect(outleftp.x(),h*0.9,randius,randius*0.2);
    QRectF maxrect(certp.x()+inirandius/2,h*0.9,randius,randius*0.2);
    painter.drawText(minrect,QString("%1").arg(m_min));
    painter.drawText(maxrect,QString("%1").arg(m_max));
    painter.restore();

    //指针
    setp = 30+1.0*m_value*(360-55)/(m_max-m_min);   //占用300度不是360 
    painter.save();
    QTransform t;
    t.translate(certp.x(),certp.y());
    t.rotate(setp);
    painter.setTransform(t);

    //QRectF rectcongradient2(-inirandius,-inirandius,inirandius*2,inirandius*2);
    //QConicalGradient congradient2(rectcongradient2.center(),360);
    congradient2.setAngle(-240+setp-30);
    //congradient2.setColorAt(0,QColor("#EC0000")); //红色
    //congradient2.setColorAt(0.5,QColor("#E5D317"));
    //congradient2.setColorAt(1.0,QColor("#2BB52C"));   //绿色
    //painter.setBrush(congradient2);

    QRectF maxrect22(0,inirandius*0.88,5,inirandius*0.1);
    painter.setBrush(/*Qt::red*/congradient);
    painter.drawRoundedRect(maxrect22,5,5);
    painter.restore();

}

void QDialCompWidget::drawRoundByPath( QPainter &painter )
{
    int w = width();
    int h = height();
    qreal randius= qMin(w*0.8/2,h*0.8/2);
    int setp = randius*0.08;
    qreal outrandius = randius + setp;
    qreal inrandius = randius - setp;

    QPointF certp(w/2,h/2);

    qreal startAngle = -60;
    qreal spanAngle = 300;
    qreal angele = 30;

    painter.save();
    //内圆
    qreal lw = inrandius*qSin(PI/6);
    qreal lh = inrandius*qCos(PI/6);

    QPointF inleftp(certp.x()-lw,certp.y()+lh);
    QPointF inrigth(certp.x()+lw,certp.y()+lh);

    QRectF rectangle(certp.x()-inrandius, certp.y()-inrandius, inrandius*2, inrandius*2);
    QPainterPath path;
    path.moveTo(inleftp);

    path.arcTo(rectangle, startAngle, spanAngle);

    //外圆
    lw = outrandius*qSin(PI/6);
    lh = outrandius*qCos(PI/6);

    QPointF outleftp(certp.x()-lw,certp.y()+lh);
    QPointF outrigth(certp.x()+lw,certp.y()+lh);
    path.moveTo(outleftp);

    QRectF rectangle2(certp.x()-outrandius, certp.y()-outrandius, outrandius*2, outrandius*2);
    path.arcTo(rectangle2, startAngle, spanAngle);


    QConicalGradient congradient(rectangle2.center(),250);
    congradient.setColorAt(0,QColor("#EC0000")); //红色
    congradient.setColorAt(0.5,QColor("#E5D317"));
    congradient.setColorAt(1,QColor("#2BB52C"));   //绿色
    painter.setBrush(congradient);
    painter.drawPath(path);
    painter.eraseRect(inleftp.x(),inleftp.y()-1,inrigth.x()-inleftp.x(),outleftp.y()-inleftp.y()+20);

    QPainterPath leftpath;
    //左侧小圆
    leftpath.moveTo(outleftp);
    qreal tmph =(outleftp.y()-inleftp.y())/2;
    qreal tmpw =(outleftp.x()-inleftp.x())/2;

    QPointF tp(outleftp.x()-tmpw,outleftp.y()-tmph);
    QRectF rmprect(tp.x()-setp,tp.y()-setp,setp*2,setp*2);
    leftpath.arcTo(rmprect,-110,200);  //角度大小取决于 angele
    //painter.setBrush(congradient);
    painter.drawPath(leftpath);

    QPainterPath rightpath;
    //右侧小圆
    rightpath.moveTo(outrigth);
    tmph =(outrigth.y()-inrigth.y())/2;
    tmpw =(outrigth.x()-inrigth.x())/2;

    QPointF righttp(outrigth.x()-tmpw,outrigth.y()-tmph);
    QRectF rmrightrect(righttp.x()-setp,righttp.y()-setp,setp*2,setp*2);
    rightpath.arcTo(rmrightrect,110,200); //角度大小取决于 angele
    //painter.setBrush(congradient);
    painter.drawPath(rightpath);
    painter.restore();


    //中间部分 白色填充
    painter.save();
    painter.setBrush(/*Qt::white*/m_oldbrush);
    painter.drawEllipse(rectangle);
    painter.restore();

    //里侧圆
    painter.save();
    qreal inirandius = inrandius*0.9;
    QPainterPath inipath;
    QRectF inirect(certp.x()-inirandius,certp.y()-inirandius,inirandius*2,inirandius*2);

    QRadialGradient radialgradient(inirect.center(),inirandius);
    QColor color_1("#2BB52C"); //绿色
    QColor color_2("#2BB52C");
    QColor color_3("#2BB52C");
    color_1.setAlpha(200);
    color_2.setAlpha(100);
    color_3.setAlpha(20);
    radialgradient.setColorAt(0.95,color_1); //
    radialgradient.setColorAt(0.99,color_2);
    radialgradient.setColorAt(1,color_3);   
    painter.setBrush(radialgradient);

    inipath.addEllipse(inirect);

    painter.drawPath(inipath);
    painter.restore();
    painter.save();
    painter.setBrush(/*Qt::white*/m_oldbrush);
    inirandius *= 0.97;
    QRectF tmprect(certp.x()-inirandius,certp.y()-inirandius,inirandius*2,inirandius*2);
    painter.drawEllipse(tmprect);
    painter.restore();

    //值value
    painter.save();
    QPen textpen;
    textpen.setColor("black");
    QFont f;
    f.setPixelSize(inirandius/2);
    painter.setPen(textpen);
    painter.setFont(f);
    painter.drawText(tmprect,Qt::AlignCenter,QString("%1%2").arg(m_value).arg(m_sufstr));
    painter.restore();

    //最大最小值
    painter.save();
    QFont f2;
    f2.setPixelSize(inirandius/4);
    painter.setPen(textpen);
    painter.setFont(f2);
    QRectF minrect(outleftp.x(),h*0.9,randius,randius*0.2);
    QRectF maxrect(certp.x()+inirandius/2,h*0.9,randius,randius*0.2);
    painter.drawText(minrect,QString("%1").arg(m_min));
    painter.drawText(maxrect,QString("%1").arg(m_max));
    painter.restore();

    //指针
    setp = 30+1.0*m_value*(360-60)/(m_max-m_min);   //占用300度不是360 
    painter.save();
    QTransform t;
    t.translate(certp.x(),certp.y());
    t.rotate(setp);
    painter.setTransform(t);


    QRectF maxrect22(0,inirandius*0.88,5,inirandius*0.1);
    painter.setBrush(/*Qt::red*/congradient);
    painter.drawRoundedRect(maxrect22,5,5);
    painter.restore();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值