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

}

复制代码
相关推荐
大风起兮122 小时前
ESP32,uart安装驱动uart_driver_install函数剖析,以及intr_alloc_flags 参数的意义
开发语言·单片机·嵌入式硬件
不是AI2 小时前
【C语言】【C++】Curl库的安装
c语言·开发语言·c++
NoneCoder2 小时前
JavaScript系列(26)--安全编程实践详解
开发语言·javascript·安全
编程小筑2 小时前
R语言的数据库编程
开发语言·后端·golang
兩尛2 小时前
maven高级(day15)
java·开发语言·maven
大熊程序猿2 小时前
golang 环境变量配置
开发语言·后端·golang
玩电脑的辣条哥3 小时前
如何用python部署本地ocr脚本
开发语言·python·ocr
Ai 编码助手3 小时前
如何使用PHP构建IoC容器,实现依赖注入!
开发语言·rpc·php
宏夏c3 小时前
【Vue】let、const、var的区别、适用场景
开发语言·javascript·ecmascript
贩卖纯净水.3 小时前
JS后盾人--再一次的走进JS?
开发语言·javascript·ecmascript