欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩🚀
本章将通过实现的例子介绍如何进行自定义 QGraphicsltem , 以及如何利用定时器来实现QGraphicsltem 动画效果 。
它是一个用于放置图元的容器,本身是不可见的,必须通过与之相连的视图类来显示及与外界进行互操作。通过 QGraphicsScene: :addltem()可以添加 一个图元到场景中。图元可以通过多个函数进行检索。 QGraphicsScene: :items()和 一些重载函数可以返回与点、矩形、多边形或向量路径相交的所有图元。 QGraphicsScene: :itemAt()返回指定点的顶层图元。
图一
添加图片到Resources中步骤如下:
图二
图三
图四
#ifndef BUTTERFLY_H
#define BUTTERFLY_H
#include
#include
#include
#include
#include
class Butterfly : public QObject,public QGraphicsItem
{
Q_OBJECT
public:
explicit Butterfly(QObject *parent = nullptr);
void timerEvent(QTimerEvent *); //定时器实现动画的原理是在定时器的 timerEvent()中对QGraphicsItem 进行重绘。
QRectF boundingRect () const; //为图元限定区域范围,所有继承自 QGraphicsItem 的自定义图元都必须实现此函数。
signals:
public slots:
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget); //重绘函数
private:
bool up;
QPixmap pix_up; //用于标志皮卡丘的位置(位于上或下),以便实现动态效果。
QPixmap pix_down; //用于保护图片
qreal angle;
public slots:
};
#endif // BUTTERFLY_H
#include "butterfly.h"
#include
const static double PI=3.1416;
Butterfly::Butterfly(QObject *parent) : QObject(parent)
{
up= true; //给标志图片位置的变量赋值
pix_up.load(":/src/up.png");
pix_down.load(":/src/down.png"); //调用 QPixmap 的 load() 函数加载所用到的图片
startTimer(100); //启动定时器,并设置时间间隔为 100 毫秒
}
QRectF Butterfly::boundingRect () const //boundingRect() 函数为图元限定区域范围。此范围是以图元自身的坐标系为基础设定的。
{
qreal adjust =2;
return QRectF (-pix_up. width() /2-adjust, -pix_up. height() /2-adjust,
pix_up. width() +adjust*2, pix_up. height() +adjust*2);
}
/*在重画函数 paint()中,首先判断当前已显示的图片是 pix_up 还是 pix_down。实现皮卡丘
上下飞舞效果时,若当前显示的是 pix_up 图片,则重绘 pix_down 图片,反之亦然。*/
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 *) //定时器的 timerEvent()函数实现皮卡丘的飞舞
{
// 边界控制
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 是相对皮卡丘
的坐标系而言的,因此应使用 mapToParent() 函数映射为场景的坐标。*/
}
#include "butterfly.h"
#include
#include
int main(int argc, char *argv[])
{
//关联一个视图
QApplication a(argc, argv);
QGraphicsScene *scene= new QGraphicsScene;
scene->setSceneRect(QRectF(-2-00,-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();
}
图形视图的动画效果会在应用程序开发中经常用到的