当我在火影中文网准备看动漫时,突然发现以下的场景,于是我也想做一个类似的效果.
完成后的效果如下:
实现这个效果主要有几个点要能够实现出来:
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下载.