一、运行效果
二、具体代码
butterfly.h
#ifndef BUTTERFLY_H
#define BUTTERFLY_H
#include <QObject>
#include <QPainter>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
class Butterfly : public QObject,public QGraphicsItem //继承自QGraphicsIten,自定义图元
{
Q_OBJECT
public:
explicit Butterfly(QObject *parent = 0);
void timerEvent(QTimerEvent *); //定时器实现动画的原理是在定时器的timerEvent()中对QGraphicsItem进行重绘
QRectF boundingRect() const; //为图元限定区域范围,所有继承自QGraphicsItem的自定义图元都必须实现次函数
protected:
void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget);
private:
bool up; //用于标志蝴蝶翅膀的位置(位于上或下)
QPixmap pix_up; //用于表示两幅蝴蝶的图片
QPixmap pix_down;
qreal angle;
};
#endif // BUTTERFLY_H
butterfly.cpp
#include "butterfly.h"
#include <math.h>
const static double PI = 3.1416;
Butterfly::Butterfly(QObject *parent) : QObject(parent)
{
up = true;
pix_up.load("up.png");
pix_down.load("down.png");
startTimer(100); //启动定时器,并设置时间间隔为100毫秒
}
QRectF Butterfly::boundingRect() const
{
qreal adjust = 2;
return QRect(-pix_up.width()/2 - adjust, -pix_up.height()/2 - adjust, pix_up.width() + adjust*2, pix_up.height() + adjust*2);
}
void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if(up)
{
painter->drawPixmap(boundingRect().topLeft(),pix_up);
up = !up;
}
else
{
painter->drawPixmap(boundingRect().topLeft(),pix_down);
up = !up;
}
}
void Butterfly::timerEvent(QTimerEvent *)
{
//限定蝴蝶飞舞的右边界
qreal EdgeX = scene()->sceneRect().right() + boundingRect().width()/2;
//限定蝴蝶飞舞的上边界
qreal EdgeTop = scene()->sceneRect().top() + boundingRect().height()/2;
//限定蝴蝶飞舞的下边界
qreal EdgeBottom = scene()->sceneRect().bottom() + boundingRect().height()/2;
if(pos().x() >= EdgeX) //若超过了右边界,则水平移回左边界
setPos(scene()->sceneRect().left(),pos().y());
if(pos().y() <= EdgeTop) //若超过了上边界,则水平移回下边界
setPos(pos().x(),scene()->sceneRect().bottom());
if(pos().y() >= EdgeBottom) //若超过了下边界,则水平移回上边界
setPos(pos().x(),scene()->sceneRect().top());
angle += (qrand()%10)/20.0;
qreal dx = fabs(sin(angle*PI)*10.0);
qreal dy = (qrand()%20)-10.0;
setPos(mapToParent(dx,dy));
//dx,dy完成蝴蝶随机飞行的路径,且dx,dy是相对于蝴蝶的坐标系而言的,因此应使用mapToParent()函数映射为场景的坐标
}
main.cpp
#include <QApplication>
#include <QGraphicsScene>
#include "butterfly.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene *scene = new QGraphicsScene;
scene->setSceneRect(QRectF(-200,-200,400,400));
Butterfly *butterfly = new Butterfly;
butterfly->setPos(-100,0);
scene->addItem(butterfly);
QGraphicsView *view = new QGraphicsView;
view->setScene(scene);
view->resize(400,400);
view->show();
return a.exec();
}