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();
}
相关推荐
Black_Friend24 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
CSUC32 分钟前
【Qt】QTreeView 和 QStandardItemModel的关系
qt
冷凝女子1 小时前
【QT】海康视频及openCv抓拍正脸接口
qt·opencv·音视频·海康
苏三有春4 小时前
PyQt5实战——UTF-8编码器功能的实现(六)
开发语言·qt
Vanranrr4 小时前
C++ QT
java·c++·qt
兆。4 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
徒步僧15 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
可峰科技16 小时前
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
开发语言·qt
我喜欢就喜欢16 小时前
基于qt vs下的视频播放
开发语言·qt·音视频
CP-DD17 小时前
Qt的架构设计
qt