《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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978625.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零构建知识库:AI如何实现“问题即答案”?

在当今这个信息爆炸的时代&#xff0c;如何高效地获取和利用知识成为了各行各业面临的共同挑战。构建知识库&#xff0c;作为整合、存储和检索信息的重要手段&#xff0c;正在逐步成为企业提升竞争力的关键。而AI技术的加入&#xff0c;更是让这一过程实现了质的飞跃&#xff0…

PhotoDoodle: Learning Artistic Image Editing from Few-Shot Examples 论文解读

目录 一、概述 二、PhotoDoodle 1、OmniEditor的预训练 2、DiT重点 3、无噪声条件范式与CFM 4、EditLoRA 4.1关于LoRA 4.2关于EditLoRA 三、相关工作 一、概述 风格化图像编辑的论文&#xff01; 介绍了PhotoDoodle&#xff0c;一个基于扩散模型的图像编辑框架&#x…

RabbitMQ操作实战

1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang&#xff1a;http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…

【Java项目】基于Spring Boot的校园博客系统

【Java项目】基于Spring Boot的校园博客系统 技术简介&#xff1a;采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介&#xff1a;校园博客系统是一个典型的管理系统&#xff0c;主要功能包括管理员&#xff1a;首页、个人中心、博主管理、文章分类管理、文章信息…

【时时三省】(C语言基础)整型数据

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 整型数据 &#xff08;1&#xff09;基本整型&#xff08;int型&#xff09; 编译系统分配给int型数据2个字节或4个字节&#xff08;由具体的C编译系统自行决定&#xff09;。在存储单元中…

Ollama下载安装+本地部署DeepSeek+UI可视化+搭建个人知识库——详解!(Windows版本)

目录 1️⃣下载和安装Ollama 1. &#x1f947;官网下载安装包 2. &#x1f948;安装Ollama 3.&#x1f949;配置Ollama环境变量 4、&#x1f389;验证Ollama 2️⃣本地部署DeepSeek 1. 选择模型并下载 2. 验证和使用DeepSeek 3️⃣使用可视化工具 1. Chrome插件-Page …

数据库的sql语句

本篇文章主要用来收集项目开发中&#xff0c;遇到的各种sql语句的编写。 1、根据user表的role_id字段&#xff0c;查询role表。 sql语句&#xff1a;使用JOIN连接两个表 SELECT u.*,r.rolename FROM user u JOIN role r ON u.role_id r.id WHERE u.id 1; 查询结果&#xff1a…

Grok 3 vs. DeepSeek vs. ChatGPT:2025终极AI对决

2025 年,AI 领域的竞争愈发激烈,三个重量级选手争夺霸主地位:Grok 3(由 xAI 开发)、DeepSeek(国内 AI 初创公司)和 ChatGPT(OpenAI 产品)。每个模型都有自己独特的优势,无论是在深度思考、速度、编程辅助、创意输出,还是在成本控制方面,都展现出强大的实力。但究竟…

手机大厂如何处理安卓分屏退出后最近任务显示一半问题?

背景&#xff1a; 近来在有学员朋友在群里讨论到了一个分屏退出后&#xff0c;在桌面最近任务中的卡片显示异常问题&#xff0c;虽然他的问题和目前市场上的最近任务显示一半情况不一样。但是这里也刚好启发了群里vip学员们对这个最近任务对分屏task只显示一半画面问题进行相关…

Spring Cloud——路由网关Zuul

??? 哈喽&#xff01;大家好&#xff0c;我是【一心同学】&#xff0c;一位上进心十足的【Java领域博主】&#xff01;??? 【一心同学】的写作风格&#xff1a;喜欢用【通俗易懂】的文笔去讲解每一个知识点&#xff0c;而不喜欢用【高大上】的官方陈述。 【一心同学】博客…

WorldQuant Brain的专属语言——Fast Expression

使用brain需要的编程语言 在使用BRAIN平台时往往不需要事先有编码背景&#xff0c;因此小白也能很快对其上手&#xff0c;但有经验的程序员来讲&#xff0c;该平台暂时没有禁止API通信低强度进行时的程序化访问&#xff08;但是非常不好意思&#x1f623;怎么访问我没找到&…

人大金仓KCA | 对象访问权限入门

人大金仓KCA | 对象访问权限入门 一、知识预备1. 对象的分类2. 对象访问权限概述3. 级联授权4. 权限描述符5. 使用EasyKStudio查看用户权限 二、案例实施1. 用户授权综合案例2. 对象的创建者默认就是对象的所属主3. 该表对象的所属主4. 对象属主的权限设置5. 授权普通用户访问对…

StrokesPlus【电脑鼠标键盘手势软件】v0.5.8.0 中文绿色便携版

前言 StrokesPlus.net是一个超方便的手势识别软件&#xff0c;它能帮你用手势来代替鼠标和键盘操作。用起来既简单又灵活&#xff0c;功能还特别强大。 操作起来非常简单&#xff0c;它有好多实用的功能&#xff0c;比如智能识别你写的字、设定手势操作的区域、模拟鼠标的各种…

springBoot统一响应类型3.1版本

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

DDD 架构之领域驱动设计【通俗易懂】

文章目录 1. 前言2. MVC 对比 DDD3. DDD 分层架构4. 完整业务流程 1. 前言 官方回答&#xff1a;DDD是一种应对复杂业务系统的设计方法&#xff0c;通过将软件设计与业务领域紧密结合&#xff0c;帮助开发人员构建清晰、可维护的领域模型。在复杂的业务系统中&#xff0c;它能…

LeetCode 889.根据前序和后序遍历构造二叉树

题目&#xff1a; 给定两个整数数组&#xff0c;preorder 和 postorder &#xff0c;其中 preorder 是一个具有 无重复 值的二叉树的前序遍历&#xff0c;postorder 是同一棵树的后序遍历&#xff0c;重构并返回二叉树。 如果存在多个答案&#xff0c;您可以返回其中 任何 一…

SSM共享充电宝系统

&#x1f345;点赞收藏关注 → 添加文档最下方联系方式咨询本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 项目视频 SS…

Android 常用命令和工具解析之存储相关

1 基本概念 2 命令解读 2.1 adb shell df df 命令主要用于需要检查文件系统上已使用和可用的磁盘空间的数量。如果没有指定文件名&#xff0c;则显示在当前所有挂载的文件系统上可用的空间。其原理是从proc/mounts 或 /etc/mtab 中检索磁盘信息。 注意&#xff1a;df命令并…

51单片机编程学习笔记——LED原理图

大纲 概览LED电路图Resistor Pack3位数电阻表示法VCC 在《51单片机编程学习笔记——编译代码点亮LED》一文中&#xff0c;我们通过下面这段代码点亮了D1和D2两个LED灯。 sbit LED1P2^0; //将P2.0管脚定义为LED1 sbit LED2P2^1; //将P2.1管脚定义为LED2 …… LED10; LED20;那么…

测试的BUG分析

在了解BUG之前,我们要先了解软件测试的生命周期,因为大多数BUG都是在软件测试的过程中被发现的 软件测试的生命周期 在了解 软件测试的生命周期 之前,我们要先了解 软件的生命周期 ,虽然他们之间只差了两个字,但是差距还是很大的 首先是 软件生命周期 ,这个是站在 软件 的角…