《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
的基础用法、QWidget
的 QPainter
旋转方法,以及更高级的优化方案。希望这些内容能帮助你在实际开发中更好地使用 Qt 动画!
源码地址:https://github.com/MingYueRuYa/QtDemo