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

本文介绍了一个使用Qt开发的WidgetSpeed类,它是一个用于显示网络速度的UI组件,通过QPainter和QTimer实时更新当前速度值。代码展示了如何设置速度值、计算文本位置以及绘制速度指示器。
摘要由CSDN通过智能技术生成

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

最终效果

ui

widgetspeed.h

#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

#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

#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

#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

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值