学习QT之图形视图实例#-飞舞的蝴蝶

本文介绍如何使用Qt自定义图元Butterfly类创建蝴蝶动画效果。Butterfly类继承自QGraphicsItem,通过定时器和重绘机制实现蝴蝶的上下翻飞和随机路径移动。代码详细展示了Butterfly类的实现,包括初始化、绘制、边界限制和动画更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、运行效果

在这里插入图片描述

二、具体代码

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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值