QT绘制仪表盘

本文分享了一个使用Qt库绘制仪表盘的Demo,通过继承QLabel并重写paintEvent函数,实现了仪表盘的显示。代码中setCurrentAndMaxNum函数可控制刻度值。此示例旨在记录和分享,帮助Qt开发者实现类似功能。
摘要由CSDN通过智能技术生成

最近在整理代码,发现以前写的绘制仪表盘Demo,特发出记录下。

显示的效果如下:

直接上代码:

#ifndef T3DASHBOARD_H
#define T3DASHBOARD_H

/**
  ******************************************************************************
  * 公司    T3
  * 文件名  T3DashBoard.h
  * 作者    TanChengkai
  * 版本    V1.0.0
  * 日期    2018.09.28
  * 说明    定制仪表盘Label类
  * 使用    只需要将自己的QLabel提升为该类(T3DashBoard),调用setCurrentAndMaxNum函数
  *        即可以调节仪表盘刻度
  ******************************************************************************
*/

#include <QLabel>
#include <QPainter>
#include <QDebug>

class T3DashBoard : public QLabel
{
public:
    explicit T3DashBoard(QWidget *parent=Q_NULLPTR);
    ~T3DashBoard();

    /**
     * @brief setCurrentAndMaxNum   设置仪表盘的当前值以及最大值
     * @param current               当前值
     * @param MaxNum                最大值
     */
    void setCurrentAndMaxNum(int current,int MaxNum);

private:

    void paintEvent(QPaintEvent *);

    void resizeEvent(QResizeEvent*);

    int         _currentScale;          //当前值与最大值的比值(百分比)
    int         _currentNum;            //当前值
    int         _MaxNum;                //最大值
};

#endif // T3DASHBOARD_H
#include "T3DashBoard.h"

T3DashBoard::T3DashBoard(QWidget *parent)
    :QLabel(parent)
{
    _currentScale = 0;
    _currentNum = 0;
    _MaxNum = 100;
}

T3DashBoard::~T3DashBoard()
{

}

void T3DashBoard::setCurrentAndMaxNum(int current, int MaxNum)
{
    if(current < 0 || MaxNum <= 0 || current > MaxNum)
        return;
    _currentNum = current;
    _MaxNum = MaxNum;
    _currentScale = _currentNum*100/_MaxNum;
    update();
}

void T3DashBoard::paintEvent(QPaintEvent *)
{

    QPainter painter(this);
    //反走样
    painter.setRenderHint(QPainter::Antialiasing);
    //使用平滑的pixmap变换算法(双线性插值算法),而不是近邻插值算法
    painter.setRenderHint(QPainter::SmoothPixmapTransform);

    //label的宽高
    int w_ = this->rect().width();
    int h_ = this->rect().height();

    int ww_ = /*10*/w_/20;//仪表盘进度条的宽度

    //仪表盘背景进度条
    painter.setPen(QPen(QColor(96,88,153),ww_*2,Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setBrush(QColor(96,88,153));
    painter.drawArc(ww_,ww_,w_ - 2*ww_,h_ - 2*ww_,210*16,-1*240*16);

    //仪表盘背景刻度
    painter.translate(w_/2,h_/2);//变化坐标系原点
    painter.save();//保存坐标系(此处为中心)
    painter.rotate(60);
    int linepenwidth_ = w_/300;
    linepenwidth_ ++;
//    qDebug()<<linepenwidth_;
    painter.setPen(QPen(QColor(160,175,209),linepenwidth_));
    int linewidth_ = w_/2 - 2*ww_ - ww_/2;
    for(int i = 0; i <= 100; i ++) {
        if(i%5 == 0) {
            painter.drawLine(0,linewidth_ - ww_,0,linewidth_);
        } else {
            painter.drawLine(0,linewidth_ - ww_*7/10,0,linewidth_);
        }
        painter.rotate(2.4);
    }
    painter.restore();//回到保存的坐标系原点(此处为中心)

    //绘画表针
    int current_ = _currentScale;
    if(current_ < 0 || current_ > 100)
        current_ = 0;
    painter.rotate(60 + _currentScale*2.4);
    int handLength_ = w_/2 - 4*ww_;
    QPolygon pts;
    pts.setPoints(4, 0,handLength_,-ww_*2/5,ww_*2,0,0, ww_*2/5,ww_*2);
    QLinearGradient rad2(0,handLength_,0,0);
    rad2.setColorAt(0,QColor(/*83,211,233*/117,230,228));
    rad2.setColorAt(0.5,QColor(124,181,232));
    rad2.setColorAt(1,QColor(/*218,119,244*/202,165,239));
    rad2.setSpread(QGradient::RepeatSpread);
    painter.setPen(Qt::NoPen);
    painter.setBrush(rad2);
    painter.drawConvexPolygon(pts);

    QLinearGradient rad3(0,-ww_/2 - 2,0,ww_/2 + 2);
    rad3.setColorAt(0,QColor(/*83,211,233*/117,230,228));
    rad3.setColorAt(0.5,QColor(124,181,232));
    rad3.setColorAt(1,QColor(/*218,119,244*/202,165,239));
    rad3.setSpread(QGradient::RepeatSpread);
    painter.setPen(Qt::NoPen);
    painter.setBrush(rad3);
    painter.drawEllipse(-ww_/2,-ww_/2,ww_,ww_);

    painter.rotate(-(60 + _currentScale*2.4));
    //返回原来坐标系
    painter.translate(-w_/2,-h_/2);

    //“电池已使用时长”文字
    painter.setPen(QPen(QColor(138,155,192),2));
    QFont font1;
    font1.setPointSize(ww_*0.9);
    painter.setFont(font1);
    painter.drawText((w_/2 - ww_*4),h_-2*ww_,ww_*8,2*ww_,Qt::AlignCenter,"电池已使用时长");

    if(_currentScale < 0 || _currentScale > 100)
        return;
    //仪表盘当前进度条
    int radius_ = w_/2 - ww_;
    int h1_ = radius_/2 + ww_ + h_/2;
    QPointF p1(0,h1_);
    QPointF p2;
    float x1_;
    if(_currentScale < 25) {
        x1_ = (w_ * 25)/100.0 + ww_;
    } else {
        x1_ = (w_ * _currentScale)/100.0 + ww_;
    }
    float y1_;
    if(_currentScale < 50) {
        y1_ = h1_ - h1_*_currentScale/50 - ww_;
    } else {
        y1_ = 0;
    }
    p2.setX(x1_);
    p2.setY(y1_);
    //设置渐变色
    QLinearGradient rad(p1,p2);
    rad.setColorAt(0,QColor(/*83,211,233*/117,230,228));
    rad.setColorAt(0.5,QColor(124,181,232));
    rad.setColorAt(1,QColor(/*218,119,244*/202,165,239));
    rad.setSpread(QGradient::RepeatSpread);

    painter.setPen(QPen(rad,ww_*2,Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setBrush(rad);
    painter.drawArc(ww_,ww_,w_ - 2*ww_,h_ - 2*ww_,210*16,-1*240*16*_currentScale/100);

    //仪表盘显示表盘数字
#if 0
    painter.translate(w_/2,h_/2);
    QLinearGradient rad11(-(w_/2 - ww_*4),0,w_/2 - ww_*4,0);
    rad11.setColorAt(0,QColor(/*83,211,233*/117,230,228));
    rad11.setColorAt(0.5,QColor(124,181,232));
    rad11.setColorAt(1,QColor(/*218,119,244*/202,165,239));
    rad11.setSpread(QGradient::RepeatSpread);
    painter.setPen(QPen(rad,2,Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setBrush(rad);

    QFont font22;
    font22.setPointSize((w_/2 - ww_*4)*0.25);
    painter.setFont(font22);

    painter.drawText(-(w_/2 - ww_*4),-ww_*2,w_/2 - ww_*4 + ww_/2,ww_*2,Qt::AlignCenter,QString::number(_currentNum));
    painter.drawLine(2*ww_,-ww_*2,-2*ww_,ww_*2);
    painter.drawText(- ww_/2,0,w_/2 - ww_*4 + ww_/2,ww_*2,Qt::AlignCenter,QString::number(_MaxNum) + "h");
#endif
    //设置当前值文字及最大值文字
    painter.translate(w_/2,h_/2 + h_/4 + ww_);
    int numWidth_ = w_/2 - ww_*4;
    QLinearGradient rad1(-(numWidth_),0,numWidth_,0);
    rad1.setColorAt(0,QColor(/*83,211,233*/117,230,228));
    rad1.setColorAt(0.5,QColor(124,181,232));
    rad1.setColorAt(1,QColor(/*218,119,244*/202,165,239));
    rad1.setSpread(QGradient::RepeatSpread);
    painter.setPen(QPen(rad,2,Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setBrush(rad);
    QFont font;
    font.setPointSize((ww_*2)*0.8);
    painter.setFont(font);
    painter.drawText(-numWidth_,-ww_,numWidth_,ww_*2,Qt::AlignCenter,QString::number(_currentNum) + "h");
    painter.drawLine(ww_/2,-ww_,-ww_/2,2*ww_);
    painter.drawText(0,0,numWidth_,ww_*2,Qt::AlignCenter,QString::number(_MaxNum) + "h");
}

void T3DashBoard::resizeEvent(QResizeEvent *)
{
    int w_ = this->width();
    int h_ = this->height();
    if(w_ > h_) {
        this->resize(w_,w_);
    } else if(w_ < h_) {
        this->resize(h_,h_);
    }
    update();
}

其中paintEvent函数,就是绘制仪表盘的重点。

在使用时,只需要将自己UI界面上的QLabel类提升为T3DashBoard类,调用类中的setCurrentAndMaxNum函数,可以控制当前刻度值及设置最大刻度值。

结尾

只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~

要在Qt的MainWindow上绘制温度仪表盘,可以使用Qt的绘图类QPainter和QPaintEvent事件。以下是实现的基本步骤: 1. 在MainWindow的头文件中声明一个函数,用于绘制温度仪表盘。 ```cpp protected: void paintEvent(QPaintEvent *event); ``` 2. 在cpp文件中实现这个函数,使用QPainter绘制温度仪表盘。 ```cpp void MainWindow::paintEvent(QPaintEvent *event) { // 创建QPainter对象 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 设置抗锯齿 // 定义变量 int side = qMin(width(), height()); // 获取窗口的最小边长 int x = (width() - side) / 2; int y = (height() - side) / 2; int radius = side / 2; // 绘制圆盘 painter.translate(x, y); // 将坐标系移动到中心点 painter.setPen(Qt::NoPen); painter.setBrush(Qt::white); painter.drawEllipse(QPointF(0, 0), radius, radius); // 绘制刻度 painter.setPen(QPen(Qt::black, 2)); // 设置画笔 painter.save(); // 保存坐标系状态 for(int i = 0; i <= 360; i += 10) { painter.rotate(10); // 旋转坐标系 if(i % 30 == 0) { painter.drawLine(0, radius - 20, 0, radius - 40); // 绘制长刻度线 painter.drawText(-10, radius - 60, QString::number(i / 30)); // 绘制刻度值 } else { painter.drawLine(0, radius - 20, 0, radius - 30); // 绘制短刻度线 } } painter.restore(); // 恢复坐标系状态 // 绘制指针 painter.save(); // 保存坐标系状态 painter.rotate(225); // 旋转坐标系 painter.setPen(QPen(Qt::red, 5)); // 设置画笔 painter.drawLine(0, 0, radius - 40, 0); // 绘制指针 painter.restore(); // 恢复坐标系状态 } ``` 3. 在MainWindow的构造函数中启用Qt的自动填充背景色功能。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setAttribute(Qt::WA_StyledBackground, true); } ``` 现在,当MainWindow被绘制时,温度仪表盘将自动绘制在窗口中央。可以通过更改指针的旋转角度来模拟不同的温度值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值