当前位置: 首页 > news >正文

《Qt动画编程实战:轻松实现头像旋转效果》

《Qt动画编程实战:轻松实现头像旋转效果》

Qt 提供了丰富的动画框架,可以轻松实现各种平滑的动画效果。其中,旋转动画是一种常见的 UI 交互方式,广泛应用于加载指示器、按钮动画、场景变换等。本篇文章将详细介绍如何使用 Qt 实现旋转动画。
在这里插入图片描述

1、效果

在这里插入图片描述

2、具体实现

#ifndef ROTATINGIMAGE_H
#define ROTATINGIMAGE_H

#include <QWidget>
#include <QLabel>
#include <QPropertyAnimation>

class RotatingImage : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)

public:
    explicit RotatingImage(QWidget *parent = nullptr);

    qreal rotation() const { return m_rotation; }
    void setRotation(qreal rotation);

    public slots:
    void startRotation();
    void stopRotation();
    void pauseRotation();
    void resumeRotation();
    void setRotationDuration(int msecs);

protected:
    void resizeEvent(QResizeEvent *event) override;

private:
    void updatePixmap();
    QPixmap getScaledPixmap() const;

private:
    QLabel *imageLabel;
    QPropertyAnimation *rotationAnimation;
    qreal m_rotation;
    QPixmap originalPixmap;
    QSize targetSize;
};

#endif // ROTATINGIMAGE_H 

#include "rotatingimage.h"
#include <QPixmap>
#include <QTransform>
#include <QVBoxLayout>
#include <QResizeEvent>
#include <QPainter>
#include <QEasingCurve>

RotatingImage::RotatingImage(QWidget *parent)
    : QWidget(parent), m_rotation(0)
{
    // 创建布局
    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    
    // 创建标签并设置图片
    imageLabel = new QLabel(this);
    imageLabel->setFixedSize(QSize(200, 200));
    originalPixmap.load(":/images/test.png");
    
    // 设置目标大小
    targetSize = QSize(200, 200);  // 比Label小一点,留出边距
    
    // 初始化图片
    updatePixmap();
    
    imageLabel->setAlignment(Qt::AlignCenter);
    imageLabel->setStyleSheet("QLabel { border-radius: 100px; background: transparent; }");
    layout->addWidget(imageLabel, 0, Qt::AlignCenter);

    // 设置动画
    rotationAnimation = new QPropertyAnimation(this, "rotation", this);
    rotationAnimation->setStartValue(0.0);
    rotationAnimation->setEndValue(360.0);
    rotationAnimation->setDuration(5000);
    rotationAnimation->setLoopCount(-1);
    
    // 使用QEasingCurve使动画更流畅
    rotationAnimation->setEasingCurve(QEasingCurve::Linear);
    rotationAnimation->start();
}

void RotatingImage::setRotation(qreal rotation)
{
    if (m_rotation != rotation) {
        m_rotation = rotation;
        updatePixmap();
    }
}

void RotatingImage::updatePixmap()
{
    QPixmap scaledPix = getScaledPixmap();
    
    // 创建一个透明的目标图片,大小与Label相同
    QPixmap targetPixmap(imageLabel->size());
    targetPixmap.fill(Qt::transparent);
    
    // 在目标图片上绘制旋转后的图片
    QPainter painter(&targetPixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    
    // 计算中心点
    QPointF center = targetPixmap.rect().center();
    painter.translate(center);
    painter.rotate(m_rotation);
    painter.translate(-center);
    
    // 计算绘制位置使图片居中
    QPointF drawPos(
        (targetPixmap.width() - scaledPix.width()) / 2.0,
        (targetPixmap.height() - scaledPix.height()) / 2.0
    );
    
    painter.drawPixmap(drawPos, scaledPix);
    painter.end();
    
    imageLabel->setPixmap(targetPixmap);
}

QPixmap RotatingImage::getScaledPixmap() const
{
    return originalPixmap.scaled(
        targetSize,
        Qt::KeepAspectRatio,
        Qt::SmoothTransformation
    );
}

void RotatingImage::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    updatePixmap();
}

void RotatingImage::startRotation()
{
    rotationAnimation->start();
}

void RotatingImage::stopRotation()
{
    rotationAnimation->stop();
}

void RotatingImage::pauseRotation()
{
    rotationAnimation->pause();
}

void RotatingImage::resumeRotation()
{
    rotationAnimation->resume();
}

void RotatingImage::setRotationDuration(int msecs)
{
    rotationAnimation->setDuration(msecs);
} 

#include <QApplication>
#include "rotatingimage.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    RotatingImage *rotatingImage = new RotatingImage();
    rotatingImage->resize(400, 400);
    rotatingImage->show();
    
    return app.exec();
} 

3| 结语

Qt 的动画系统提供了丰富的 API,可以方便地实现旋转动画。本文介绍了 QPropertyAnimation 的基础用法、QWidgetQPainter 旋转方法,以及更高级的优化方案。希望这些内容能帮助你在实际开发中更好地使用 Qt 动画!
源码地址:https://github.com/MingYueRuYa/QtDemo

http://www.dtcms.com/a/41162.html

相关文章:

  • 人工智能 pytorch篇
  • 构建动态URL查询字符串以导出报警统计数据
  • C++:指针函数与函数指针
  • Grafana11.5.2 | 安装配置步骤(已成功安装)
  • AI开发利器:Anaconda
  • Golang快速上手01/Golang基础
  • 深入miniqmt:掌握创建交易对象的关键步骤
  • 异常c/c++
  • 原码反码补码计算以及按位取反操作
  • Linux 环境“从零”部署 MongoDB 6.0:mongosh 安装与数据操作全攻略
  • Node.js安装与学习的简单记录
  • C++三大特性之多态
  • Mission Planner MP地面站添加Cesium三维地图
  • 我国公共数据授权运营的实践调查与展望——目标定位、行动要素、政策保障及平台支持
  • JavaScript 简单类型与复杂类型-简单类型的内存分配
  • 【DeepSeek开发】Python实现纽约房价热力图
  • 基于LangChain4j调用火山引擎DeepSeek R1搭建RAG知识库实战指南
  • FreeRTOS-计数型信号量
  • 【OpenCV C++】图像增强:三种锐化方式,图像清晰度增强
  • TCP基本入门-简单认识一下什么是TCP
  • 关于“你对 Spring Cloud 的理解”
  • SpringBoot 中的 Redis 序列化
  • 【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建
  • DeepSeek开源周 Day04:从DualPipe聊聊大模型分布式训练的并行策略
  • 微信小程序细小知识累计记录
  • 1. HTTP 数据请求
  • 期权帮|国内期权交易投资人做卖出期权价差交易收取的保证金是单边的还是双向的?
  • SpringBoot3—快速入门
  • 大白话css第三章实践与提升
  • seacmsv9报错注入管理员账号密码,order by 注入,如何解决 information_schema关键字被过滤掉了