Qt利用paintEvent自制一个加载动画

创建

我们先创建一个UI类

选择widget

废话不多说直接上代码:

头文件

#ifndef LOADINGWIDGET_H
#define LOADINGWIDGET_H

#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>

namespace Ui {
class LoadingWidget;
}

class LoadingWidget : public QWidget
{
    Q_OBJECT

public:
    explicit LoadingWidget(QWidget *parent = nullptr);
    ~LoadingWidget();
    void startLoading();
    void stopLoading();

protected:
    void paintEvent(QPaintEvent *event) override;

private slots:
    void onTimeout();


private:
    QTimer *timer;
    int angle;
    Ui::LoadingWidget *ui;
};

#endif // LOADINGWIDGET_H

CPP文件 

#include "loadingwidget.h"
#include "ui_loadingwidget.h"

LoadingWidget::LoadingWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::LoadingWidget)
{
    ui->setupUi(this);
    angle = 0;
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&LoadingWidget::onTimeout);
    timer->setInterval(40);
}

LoadingWidget::~LoadingWidget()
{
    delete ui;
}

void LoadingWidget::startLoading()
{
    angle=0;
    timer->start();
}

void LoadingWidget::stopLoading()
{
    timer->stop();
}

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

    int side = qMin(width(), height());
    int x = qRound((width() - side) / 2.0); // 使用 qRound 调整 x 计算
    int y = qRound((height() - side) / 2.0); // 使用 qRound 调整 y 计算

    // 创建渐变
    QConicalGradient gradient(width() / 2, height() / 2, angle);
    gradient.setColorAt(0, Qt::white);
    gradient.setColorAt(0.5, Qt::gray);
    gradient.setColorAt(1, Qt::black);

    // 设置渐变笔刷
    QBrush brush(gradient);
    painter.setBrush(brush);

    // 计算适应窗口尺寸的线宽
    qreal maxLineWidthPercent = 0.2; // 设置一个较小的线宽百分比
    qreal lineWidth = maxLineWidthPercent * side; // 适应窗口尺寸
    painter.setPen(QPen(brush, lineWidth));
    painter.drawEllipse(x + lineWidth / 2, y + lineWidth / 2, side - lineWidth, side - lineWidth);

    // 计算中心圆的位置和半径
    qreal centerRadiusPercent = 0.8; // 设置内部圆圈半径百分比
    int centerRadius = centerRadiusPercent * side / 2;  // 调整内部圆圈半径
    QPoint centerPoint(width() / 2, height() / 2);

    // 画中心空的圆
    // 获取parent的背景色
    QColor parentBackgroundColor = parentWidget() ? parentWidget()->palette().color(QPalette::Background) : Qt::white;
    // 画中心空的圆,颜色设置为parent的背景色
    painter.setBrush(parentBackgroundColor);

    painter.drawEllipse(centerPoint, centerRadius, centerRadius);
}

void LoadingWidget::onTimeout()
{
    angle += 15;
    if (angle > 360)
        angle -= 360;

    update();
}

使用方法

在耗时操作的地方添加一个Widget控件,然后提升为LoadingWidget,调用startloding函数即可

注意:最好将widget宽高设为10的倍数,否则可能在边缘出现显示小bug。

运行效果

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值