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

本文介绍了如何在Qt应用中创建一个名为CustomWidget的自定义控件,包括使用QT+coreguicharts扩展,以及如何处理版本兼容性和使用QPainter绘制速度指示器,展示了初始化状态设置和定时更新速度值的代码片段。
摘要由CSDN通过智能技术生成

ui

CustomWidget.pro

QT       += core gui charts

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

#msvc编译器指定执行字符集
msvc:QMAKE_CXXFLAGS += -execution-charset:utf-8

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp \
    widgetspeed.cpp

HEADERS += \
    widget.h \
    widgetspeed.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

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、付费专栏及课程。

余额充值