QGraphicsItem中水平动画使用QGraphicsItemAnimation和QTimeLine即可实现,而旋转动画须使用QTimeLine和QTransform来实现。QWidget中也可实现相同的效果。
(2)绕Z轴旋转
rotate()参数为Qt::ZAxis
(1)main.cpp
#include "mainwindow.h" #include <QApplication> #include <QtGui> #include <QGraphicsScene> 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 <QMainWindow> #include <QGraphicsView> #include <QGraphicsItem> #include <QTimer> 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 <QTimer> #include <QDebug> 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 <QApplication> #include <QtGui> #include <QGraphicsScene> 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 <QMainWindow> #include <QGraphicsView> #include <QGraphicsItem> #include <QTimeLine> #include <QDebug> #include <QPushButton> #include <QGraphicsProxyWidget> 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() { QList<QGraphicsItem *>itemList = this->items(); dynamic_cast<TxtItem *>(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)运行过程中会产生虚影,暂时不清楚怎么有什么参数可以优化。