加载等待动画实现------转圈圈
效果图:(看封面最好)
关键要点
- 流畅的动画 :
- 使用
QTimer
每 50 毫秒更新一次动画,确保动画流畅。
- 使用
- 视觉效果 :
- 使用
QPainter
的平滑像素转换和抗锯齿选项,提高动画的视觉质量。 - 设置窗口属性为透明背景,使动画可以覆盖在其他内容上。
- 使用
- 性能优化 :
- 只在需要时更新动画,避免不必要的重绘。
关键要点
- 流畅的动画 :
- 使用
QTimer
每 50 毫秒更新一次动画,确保动画流畅。
- 使用
- 视觉效果 :
- 使用
QPainter
的平滑像素转换和抗锯齿选项,提高动画的视觉质量。 - 设置窗口属性为透明背景,使动画可以覆盖在其他内容上。
- 使用
- 性能优化 :
- 只在需要时更新动画,避免不必要的重绘。
实现代码:
cpp
//WaitWidge.h//
#ifndef WAITWIDGE_H
#define WAITWIDGE_H
#include <QWidget>
#include <QPaintEvent>
// WaitWidge 类继承自 QWidget,用于显示等待动画
class WaitWidge : public QWidget
{
Q_OBJECT
public:
WaitWidge(QWidget *parent = nullptr);
~WaitWidge();
protected:
// 重载 paintEvent 方法,用于自定义绘制
void paintEvent(QPaintEvent *) override;
private:
QPixmap* m_pPixmap; // 用于储存等待动画图片
QTimer* m_pTimer; // 用于更新动画
};
//WaitWidge.cpp//
#endif // WAITWIDGE_H
#include "WaitWidge.h"
#include <QPainter>
#include <QTimer>
// 静态变量,用于记录旋转次数
static int count = 0;
WaitWidge::WaitWidge(QWidget *parent)
: QWidget(parent)
{
// 设置窗口标志为无边框和工具窗口
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
// 设置窗口属性为透明背景
setAttribute(Qt::WA_TranslucentBackground, true);
// 加载等待动画图片
m_pPixmap = new QPixmap("://wait.png");
// 创建定时器,用于定时更新动画
m_pTimer = new QTimer(this);
// 连接定时器的 timeout 信号到更新槽函数
connect(m_pTimer, &QTimer::timeout, [=]{
update(); // 更新窗口,触发 paintEvent
});
// 启动定时器,每 50 毫秒触发一次
m_pTimer->start(50);
}
WaitWidge::~WaitWidge() {}
// 重载 paintEvent 方法
void WaitWidge::paintEvent(QPaintEvent *)
{
// 创建 QPainter 对象,用于绘制
QPainter painter(this);
// 设置绘制选项
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::NoBrush);
// 计算绘制区域,使图片居中
QRect trect((rect().width() - 128)/2, (rect().height() - 128)/2, 128, 128);
// 创建 QMatrix 对象,用于旋转图片
QMatrix matrix;
// 旋转图片,每次旋转 10 度
matrix.rotate((10 * (count++)) % 360);
// 绘制旋转后的图片
painter.drawPixmap(trect, m_pPixmap->transformed(matrix, Qt::SmoothTransformation));
}
使用方法
-
创建等待动画对象:
cppWaitWidge* waitWidget = new WaitWidge(this);
-
显示等待动画:
cppwaitWidget->show();
-
隐藏等待动画:
cppwaitWidget->hide();
调用实例代码
c++
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "WaitWidge.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow() = default;
protected:
void resizeEvent(QResizeEvent* event) override;
void showEvent(QShowEvent* event) override;
private:
void centerWaitWidget();
private:
WaitWidge* waitWidget;
};
#endif // MAINWINDOW_H
#include "MainWindow.h"
#include <QPushButton>
#include <QVBoxLayout>
#include <QResizeEvent>
#include <QShowEvent>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), waitWidget(new WaitWidge(this))
{
// 设置主窗口的大小
setFixedSize(400, 300);
// 创建一个按钮,用于显示和隐藏等待动画
QPushButton* button = new QPushButton("Toggle Wait Widget", this);
connect(button, &QPushButton::clicked, [this]{
if (waitWidget->isVisible())
{
waitWidget->hide();
}
else {
waitWidget->show();
centerWaitWidget(); // 显示时重新计算位置
}
});
// 创建一个布局,将按钮添加到布局中
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(button);
// 创建一个中心部件,并将布局设置为中心部件的布局
QWidget* centralWidget = new QWidget(this);
centralWidget->setLayout(layout);
setCentralWidget(centralWidget);
// 设置等待动画组件的初始大小
waitWidget->setFixedSize(128, 128);
waitWidget->hide(); // 初始时隐藏等待动画
}
void MainWindow::resizeEvent(QResizeEvent* event)
{
QMainWindow::resizeEvent(event);
centerWaitWidget(); // 窗口大小改变时重新计算位置
}
void MainWindow::showEvent(QShowEvent* event)
{
QMainWindow::showEvent(event);
centerWaitWidget(); // 窗口显示时计算位置
}
void MainWindow::centerWaitWidget()
{
// 获取主窗口的全局坐标
QPoint globalPos = mapToGlobal(rect().topLeft());
int x = globalPos.x() + (width() - waitWidget->width()) / 2;
int y = globalPos.y() + (height() - waitWidget->height()) / 2;
waitWidget->move(x, y);
}
= mapToGlobal(rect().topLeft());
int x = globalPos.x() + (width() - waitWidget->width()) / 2;
int y = globalPos.y() + (height() - waitWidget->height()) / 2;
waitWidget->move(x, y);
}