Qt: 圖片旋轉的特效
阿新 • • 發佈:2019-02-14
當我在火影中文網準備看動漫時,突然發現以下的場景,於是我也想做一個類似的效果.
完成後的效果如下:
實現這個效果主要有幾個點要能夠實現出來:
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();
}