Qt: 图片旋转的特效

当我在火影中文网准备看动漫时,突然发现以下的场景,于是我也想做一个类似的效果.
这里写图片描述

完成后的效果如下:
这里写图片描述

实现这个效果主要有几个点要能够实现出来:
1.如何实现旋转效果.
2.重写进入控件和离开控件的虚函数.

首先,重写了一个QLabel类.

“MyLabel.h”的代码:

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>
#include <QPixmap>
#include <QEvent>
#include <QMatrix>
#include <QTimer>

class MyLabel : public QLabel
{
    Q_OBJECT

public:
    MyLabel(QPixmap, QWidget *parent = 0);
    ~MyLabel();
protected:
    void enterEvent(QEvent *event);
    void leaveEvent(QEvent *event);
    void timerEvent(QTimerEvent *event);
private:
    //记录定时器id.
    int m_enterId;
    int m_leaveId;
    //保存label显示的图片.
    QPixmap m_pixmap;
    //记录旋转角度.
    float m_rotateAngle;

};

#endif // MYLABEL_H

“MyLabel.cpp”下的实现代码:

#include "MyLabel.h"

const float FixedAngle = 22.5f;
const int Time = 10;

MyLabel::MyLabel(QPixmap pixmap,QWidget *parent)
    : QLabel(parent)
{
    //给一些成员变量归零.
    m_rotateAngle = 0;
    m_enterId = 0;
    m_leaveId = 0;
    m_pixmap = pixmap;
    //设置显示的图片.
    this->setPixmap(m_pixmap);
}

MyLabel::~MyLabel()
{

}
void MyLabel::enterEvent(QEvent *event)
{
    if (m_leaveId == 0)
    {
        m_enterId = this->startTimer(Time, Qt::PreciseTimer);
        qDebug("enter");
    }
}
void MyLabel::leaveEvent(QEvent *event)
{
    if (m_enterId == 0)
    {
        m_leaveId = this->startTimer(Time, Qt::PreciseTimer);
        qDebug("leave");
    }
}
void MyLabel::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == m_enterId)
    {
        QMatrix matrix;
        m_rotateAngle += FixedAngle;
        //设置旋转的操作.
        matrix.rotate(m_rotateAngle);
        //获取旋转后的图片.
        QPixmap temp = m_pixmap.transformed(matrix);
        this->setPixmap(temp);

        //当转到一圈后.
        if (m_rotateAngle == 360)
        {
            //归零并杀死计时器.
            m_rotateAngle = 0;
            this->killTimer(m_enterId);
            m_enterId = 0;
        }
    }
    else if (event->timerId() == m_leaveId)
    {
        QMatrix matrix;
        m_rotateAngle -= FixedAngle;
        matrix.rotate(m_rotateAngle);
        QPixmap temp = m_pixmap.transformed(matrix);
        this->setPixmap(temp);

        //当转到一圈后.
        if (m_rotateAngle == -360)
        {
            //归零并杀死计时器.
            m_rotateAngle = 0;
            this->killTimer(m_leaveId);
            m_leaveId = 0;
        }
    }
}

“c.h”的内容:

#ifndef C_H
#define C_H

#include <QtWidgets/QWidget>
#include "ui_c.h"
#include "MyLabel.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
using namespace std;

class MyLabel;
class c : public QWidget
{
    Q_OBJECT

public:
    c(QWidget *parent = 0);
    ~c();

private:
    Ui::cClass ui;
    vector<MyLabel*> m_labelArray;
};

#endif // C_H

对于”c.cpp”的实现代码:

#include "c.h"


c::c(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //设置背景为灰色.
    this->setPalette(QPalette(QPalette::Window,Qt::gray));

    //初始化9个label框.
    for (int i = 0; i < 9; ++i)
    {
        MyLabel *label = new MyLabel(QPixmap(QString("Pixmaps/%1.png").arg(i)));
        label->resize(100 * sqrt(2), 100 * sqrt(2));
        //设置居中.
        label->setAlignment(Qt::AlignCenter);
        //设置边框.
        label->setFrameShape(QFrame::StyledPanel);
        m_labelArray.push_back(label);
    }

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setSpacing(50);

    int n = 0;
    for (int i = 0; i < 3; ++i)
    {
        QHBoxLayout *hLayout = new QHBoxLayout();
        hLayout->setSpacing(50);
        for (int j = 0; j < 3; ++j)
        {
            hLayout->addWidget(m_labelArray[n++]);
        }
        layout->addLayout(hLayout);
    }
    auto length = 100 * sqrt(2) * 3 + 150;
    this->setFixedSize(length, length);

}

c::~c()
{

}

最后的main.cpp

#include "c.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    c w;
    w.show();
    return a.exec();
}

源码在http://download.csdn.net/download/qq_37233607/10215138下载.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值