Qt 小功能:加载等待动画——转圈圈

加载等待动画实现------转圈圈

效果图:(看封面最好)

关键要点

  1. 流畅的动画
    • 使用 QTimer 每 50 毫秒更新一次动画,确保动画流畅。
  2. 视觉效果
    • 使用 QPainter 的平滑像素转换和抗锯齿选项,提高动画的视觉质量。
    • 设置窗口属性为透明背景,使动画可以覆盖在其他内容上。
  3. 性能优化
    • 只在需要时更新动画,避免不必要的重绘。

关键要点

  1. 流畅的动画
    • 使用 QTimer 每 50 毫秒更新一次动画,确保动画流畅。
  2. 视觉效果
    • 使用 QPainter 的平滑像素转换和抗锯齿选项,提高动画的视觉质量。
    • 设置窗口属性为透明背景,使动画可以覆盖在其他内容上。
  3. 性能优化
    • 只在需要时更新动画,避免不必要的重绘。

实现代码:

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));
}

使用方法

  1. 创建等待动画对象

    cpp 复制代码
    WaitWidge* waitWidget = new WaitWidge(this);
  2. 显示等待动画

    cpp 复制代码
    waitWidget->show();
  3. 隐藏等待动画

    cpp 复制代码
    waitWidget->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);

}

复制代码
相关推荐
座山雕~1 分钟前
测试接口-----详细
开发语言·postman
小龙报11 分钟前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
木木em哈哈18 分钟前
有关于cnb自动化的脚本补全
服务器·开发语言·pygame
星释19 分钟前
Rust 练习册 :Poker与扑克牌游戏
开发语言·游戏·rust
晨非辰28 分钟前
【数据结构初阶】--从排序算法原理分析到代码实现操作,参透插入排序的奥秘!
c语言·开发语言·数据结构·c++·算法·面试·排序算法
Jonathan Star33 分钟前
Next.js、NestJS、Nuxt.js 是 **Node.js 生态中针对不同场景的框架**
开发语言·javascript·node.js
zhangyao9403303 小时前
关于js导入Excel时,Excel的(年/月/日)日期是五位数字的问题。以及对Excel日期存在的错误的分析和处理。
开发语言·javascript·excel
骑驴看星星a4 小时前
【Three.js--manual script】4.光照
android·开发语言·javascript
星释5 小时前
Rust 练习册 :Leap与日期计算
开发语言·后端·rust
悟能不能悟6 小时前
java的java.sql.Date和java.util.Date的区别,应该怎么使用
java·开发语言