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();
}
相关推荐
慧都小项4 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
Quz4 天前
QML SwipeDelegate 滑动委托
qt
Quz4 天前
QML 列表中的四种委托:ItemDelegate、CheckDelegate、RadioDelegate、SwitchDelegate
qt
实心儿儿4 天前
Qt — 显示类控件
qt
江湖人称菠萝包4 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter9-Qt Charts
笔记·qt·qt5
扶尔魔ocy4 天前
【QT android】环境安装及第一个QT项目
qt·andriod开发
江湖人称菠萝包4 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter10-Data Visualization
笔记·qt·qt5
Cx330❀5 天前
Qt 常用控件属性与底层机制详解:从窗口半透明、浮点数陷阱到 QSS 与焦点策略
qt·ui·图形渲染
Quz5 天前
QML DelegateChooser:多条件组合与按列选择委托
qt
Quz5 天前
QML DelegateChooser:按角色选择委托与按索引选择委托
qt