创建
我们先创建一个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。