QPaint绘制自定义仪表盘组件04

网上视频抄的,用来自己看一下,看完就删掉

最终效果

ui

widgetspeed.h

cpp 复制代码
#ifndef WIDGETSPEED_H
#define WIDGETSPEED_H

#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QDebug>
#include <QFont>
#include <QPen>
#include <QtMath>

class WidgetSpeed : public QWidget
{
    Q_OBJECT
public:
    explicit WidgetSpeed(QWidget *parent = nullptr);

    //当前速度值 Mb/s
    void setCurSpeed(int value);

    //计算文本位置
    void calcTextPos(QPainter *painter, int radius);

protected:
    void paintEvent(QPaintEvent *event);

private:
    int m_curSpeed = 200;     //当前速度
    int m_maxLimit = 1000;    //最大速度
};

#endif // WIDGETSPEED_H

widgetspeed.cpp

cpp 复制代码
#include "widgetspeed.h"

WidgetSpeed::WidgetSpeed(QWidget *parent) : QWidget(parent)
{

}

void WidgetSpeed::setCurSpeed(int value)
{
    this->m_curSpeed = value;

    update();
}

void WidgetSpeed::calcTextPos(QPainter *painter, int radius)
{
    painter->save();
    radius = radius * 0.85;

    QPen pen;
    pen.setColor(Qt::white);
    painter->setPen(pen);

    int startAngle = 210;
    int endAngle = -30;
    int duration = 10;
    double startRad = (startAngle) * (M_PI / 180);
    double deltaRad = (startAngle - endAngle) * (M_PI / 180) / duration;

    for (int i=0; i<=duration; i++)
    {
        double sina = qSin(startRad - i * deltaRad);
        double cosa = qCos(startRad - i * deltaRad);

        QString strValue = QString("%1").arg(i * 100);
        // double textWidth = fontMetrics().horizontalAdvance(strValue);
        double textWidth = fontMetrics().width(strValue);
        double textHeight = fontMetrics().height();
        int x = radius * cosa - textWidth / 2;
        int y = -radius * sina + textHeight / 4;
        painter->drawText(x, y, strValue);
    }

    painter->restore();
}

void WidgetSpeed::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    int minValue = (width() > height()) ? height() : width();
    int radius = minValue * 0.45;
    int startAngle = -30;
    int spanAngle = 240;
    int range = spanAngle;
    int markLength = radius / 2;

    //重置中心
    QPoint center = QPoint(width()/2, height()/2);
    painter.translate(center);
    QRect rect(-radius, -radius, radius * 2, radius * 2);
    float percent = (float)m_curSpeed / (float)m_maxLimit;

    QPen pen;
    pen.setWidth(16);

    //绘制底盘
    painter.save();
    pen.setColor(QColor(49, 55, 77));
    painter.setPen(pen);
    painter.drawArc(rect, startAngle*16, spanAngle*16);

    pen.setColor(QColor(0, 202, 205));
    painter.setPen(pen);
    startAngle = 210;
    spanAngle = -percent * range;
    painter.drawArc(rect, startAngle*16, spanAngle*16);
    painter.restore();

    //绘制文字
    painter.save();
    pen.setColor(QColor(0, 202, 205));
    QFont font;
    font.setPixelSize(16);
    painter.setFont(font);
    painter.setPen(pen);
    QString info = QString("%1 Mb/s").arg(m_curSpeed);
    painter.drawText(-30, 50, info);
    painter.restore();

    calcTextPos(&painter, radius);

    //绘制指针
    painter.save();
    QLinearGradient grad(0, 0, markLength, 0);
    grad.setColorAt(0, Qt::gray);
    grad.setColorAt(1.0, QColor(0, 202, 205));
    pen.setBrush(QBrush(grad));
    pen.setWidth(14);
    painter.setPen(pen);
    spanAngle = percent * range;
    painter.rotate(-210 + spanAngle);
    painter.drawLine(0, 0, markLength, 0);
    painter.restore();

}

widget.h

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>
#include <QTime>
#include "widgetspeed.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void initState();
    int  creteRandValue();
private:
    Ui::Widget *ui;

    WidgetSpeed *m_speedUp = nullptr;
    WidgetSpeed *m_speedDown = nullptr;
    int index = 0;
    QTimer timer;   //定时器
};
#endif // WIDGET_H

widget.cpp

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    initState();
}

Widget::~Widget()
{
    timer.stop();
    delete ui;
}

void Widget::initState()
{
    this->resize(900, 850);
    this->setWindowTitle("CustomWidget");

    m_speedUp = new WidgetSpeed();
    ui->layoutSpeedUp->addWidget(m_speedUp);
    m_speedDown = new WidgetSpeed();
    ui->layoutSpeedDown->addWidget(m_speedDown);

    connect(&timer, &QTimer::timeout, [=]()
    {
        int value = creteRandValue();
        m_speedUp->setCurSpeed(value);
        m_speedDown->setCurSpeed(value * 0.8);
    });
    timer.start(100);
}

int Widget::creteRandValue()
{
    QTime time = QTime::currentTime();
    qsrand(time.second() * 1000);

    //1000内随机
    int rand = 1000;
    int value = qrand() % rand;
    return value;
}

main.cpp

cpp 复制代码
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
相关推荐
水煎包V:YEDIYYDS8889 小时前
QT QML 实现的摇杆按钮,类似王者荣耀 左边方向导航键
qt·qml·摇杆按钮·导航键
winfield82110 小时前
MCP 协议详解
开发语言·网络·qt
秦jh_12 小时前
【Qt】常用控件(上)
服务器·数据库·qt
刃神太酷啦12 小时前
C++ list 容器全解析:从构造到模拟实现的深度探索----《Hello C++ Wrold!》(16)--(C/C++)
java·c语言·c++·qt·算法·leetcode·list
水煎包V:YEDIYYDS88812 小时前
QT modbus 通信教程,把modbus封装到线程单例中,在线程内完成数据收发,解析。把重要数据以信号方式通知到qml层展示,解决UI卡顿
qt·modbus·线程服务
东哥很忙XH13 小时前
python使用PyQt5开发桌面端串口通信
开发语言·驱动开发·python·qt
汪宁宇14 小时前
如何在QT5+MinGW环境中编译使用QGIS开发地图应用
c++·qt·qgis·mingw·地图库
刺客xs15 小时前
Qt-----QSS样式表
开发语言·javascript·qt
qq_4017004115 小时前
QProgressBar+QSS 进度条
qt
小灰灰搞电子17 小时前
Qt PDF模块详解
数据库·qt·pdf