QGraphicsItem中水平动画使用QGraphicsItemAnimation和QTimeLine即可实现,而旋转动画须使用QTimeLine和QTransform来实现。QWidget中也可实现相同的效果。
(2)绕Z轴旋转
rotate()参数为Qt::ZAxis
(1)main.cpp
#include "mainwindow.h"
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TxtItem *txtItem = new TxtItem;
txtItem->setText("How are you, my friend!!");
QGraphicsScene scene;
MyQView mqv(&scene);
scene.addItem(txtItem);
mqv.show();
return a.exec();
}
(2)mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
class MyQView : public QGraphicsView {
Q_OBJECT
public:
MyQView(QGraphicsScene *scene);
~MyQView();
};
class TxtItem : public QObject, public QGraphicsItem {
Q_OBJECT
public:
explicit TxtItem(QGraphicsItem *parent = 0);
~TxtItem();
void paint(QPainter * painter,
const QStyleOptionGraphicsItem * option,
QWidget * widget = 0);
QRectF boundingRect () const;
void setText(const QString &newText);
public slots:
void flip();
private slots:
void animateFilp();
private:
QTimer *tm;
int m_angle; //rotation angle
int m_delta;
int m_current; //store rotation direction
QString m_text;
};
#endif // MAINWINDOW_H
(3)mainwindow.cpp
#include "mainwindow.h"
#include
#include
MyQView::MyQView(QGraphicsScene *scene) : QGraphicsView(scene)
{
setGeometry(100, 100, 800, 600);
setWindowFlags(Qt::FramelessWindowHint);
}
MyQView::~MyQView()
{
}
TxtItem::TxtItem(QGraphicsItem *parent)
: QGraphicsItem(parent)
{
m_angle = 0;
m_delta = 0;
m_current = 0;
//setOpacity(0.5);
tm = new QTimer;
tm->setInterval(2000);
connect(tm, SIGNAL(timeout()), this, SLOT(flip()));
tm->start();
//QTimer::singleShot(10, this, SLOT(flip()));
//flip();
}
TxtItem::~TxtItem()
{
if (tm) {
if (tm->isActive()) tm->stop();
delete tm;
tm = NULL;
}
}
void TxtItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QBrush brush(Qt::cyan);
painter->setBrush(brush);
painter->drawRect(boundingRect());
painter->setPen(QPen(Qt::magenta, 10));
painter->drawText(boundingRect().x() + 180, boundingRect().y(),
boundingRect().width(), boundingRect().height(),
Qt::AlignLeft | Qt::AlignVCenter, m_text);
}
QRectF TxtItem::boundingRect() const
{
return QRectF(0, 0, 500, 300);
}
void TxtItem::setText(const QString &newText) {
m_text = newText;
}
void TxtItem::animateFilp()
{
m_angle += m_delta;
if(180 == m_angle) {
m_current ^= 1;
}
QRectF r = boundingRect();
setTransform(QTransform()
.translate(r.width() / 2, r.height() /2)
.rotate(m_angle, Qt::YAxis)
.translate(-r.width() / 2, -r.height() / 2));
if((0 == m_current && m_angle > 0) || (1 == m_current && m_angle < 360)) {
QTimer::singleShot(25, this, SLOT(animateFilp()));
}
}
void TxtItem::flip()
{
m_delta = (m_current == 0 ? 9 : -9);
animateFilp();
}
要想控制旋转的坐标轴,修改setTransform()中rotate()的第二个参数,默认是绕Z轴旋转。若只想旋转一次,则在构造函数中关闭定时器,使用QTimer::singleShot(10, this, SLOT(flip()));或直接调用flip()即可。
#include "mainwindow.h"
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TxtItem *txtItem = new TxtItem;
txtItem->setText("How are you, my friend!!");
QGraphicsScene scene;
MyQView mqv(&scene);
scene.addItem(txtItem);
mqv.show();
return a.exec();
}
(2)mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
class MyQView : public QGraphicsView {
Q_OBJECT
public:
MyQView(QGraphicsScene *scene);
~MyQView();
private slots:
void slotClickedBtn();
};
class TxtItem : public QObject, public QGraphicsItem {
Q_OBJECT
public:
explicit TxtItem(QGraphicsItem *parent = 0);
~TxtItem();
void paint(QPainter * painter,
const QStyleOptionGraphicsItem * option,
QWidget * widget = 0);
QRectF boundingRect () const;
void setText(const QString &newText);
void setStatus();
private slots:
void animateFilp(qreal value);
private:
QString m_text;
QTimeLine *timeLine;
};
#endif // MAINWINDOW_H
(3)mainwindow.cpp
#include "mainwindow.h"
MyQView::MyQView(QGraphicsScene *scene) : QGraphicsView(scene)
{
setGeometry(100, 100, 800, 600);
setWindowFlags(Qt::FramelessWindowHint);
QPushButton *button = new QPushButton(this);
connect(button, SIGNAL(clicked()), this, SLOT(slotClickedBtn()));
button->setText(tr("Change"));
button->move(350, 100);
}
MyQView::~MyQView()
{
}
void MyQView::slotClickedBtn()
{
QListitemList = this->items();
dynamic_cast(itemList.at(0))->setStatus();
}
TxtItem::TxtItem(QGraphicsItem *parent)
: QGraphicsItem(parent)
{
timeLine = new QTimeLine(1500, this);
timeLine->setDirection(QTimeLine::Forward);
connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateFilp(qreal)));
timeLine->start();
}
TxtItem::~TxtItem()
{
if (timeLine) {
if (timeLine->state() == QTimeLine::Running)
timeLine->stop();
delete timeLine;
timeLine = NULL;
}
}
void TxtItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QBrush brush(Qt::cyan);
painter->setBrush(brush);
painter->drawRect(boundingRect());
painter->setPen(QPen(Qt::magenta, 10));
painter->drawText(boundingRect().x() + 180, boundingRect().y(),
boundingRect().width(), boundingRect().height(),
Qt::AlignLeft | Qt::AlignVCenter, m_text);
}
QRectF TxtItem::boundingRect() const
{
return QRectF(0, 0, 500, 300);
}
void TxtItem::setText(const QString &newText) {
m_text = newText;
}
void TxtItem::setStatus()
{
if (timeLine->state() == QTimeLine::Running) {
return;
}
if (timeLine->currentValue() == 0) {
timeLine->setDirection(QTimeLine::Forward);
timeLine->start();
}
else {
timeLine->setDirection(QTimeLine::Backward);
timeLine->start();
}
}
void TxtItem::animateFilp(qreal value)
{
QRectF r = boundingRect();
setTransform(QTransform()
.translate(r.width() / 2, r.height() /2)
.rotate(180 *value, Qt::YAxis)
.translate(-r.width() / 2, -r.height() / 2));
}
运行:
(1)运行过程中会产生虚影,暂时不清楚怎么有什么参数可以优化。