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

}

复制代码
相关推荐
迷迭所归处4 分钟前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ33 分钟前
Java 23 的12 个新特性!!
java·开发语言·学习
leon62534 分钟前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab
锦亦之22332 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
我是苏苏2 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
姜太公钓鲸2332 小时前
c++ static(详解)
开发语言·c++
菜菜想进步2 小时前
内存管理(C++版)
c语言·开发语言·c++
2301_789985942 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习
知星小度S2 小时前
C语言——自定义类型
c语言·开发语言
快乐牌刀片882 小时前
web - JavaScript
开发语言·前端·javascript