欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩🚀
文章目录
前言
本章节会给大家带来基于图元创建 GraphicsItem V1.1开发升级到图元创建 GraphicsItem V1.2开发的解析。
一、 GraphicsItem V1.2升级图元星星移动的功能解析
1.1、增添Startltem类
向项目中添加一个新的 C++类,类名命名为" Startltem",。 Startltem 类继承自 QGraphicsltem 类,实际上是一个图片图元。
1.2、图元框架中星星移动的图元
(1)在 “mainwindow.h” 文件中添加代码如下:
public slots:
void slotAddAnimationItem();
private:
QAction *addAnimItemAct;
(2)在 “mainwindow.cpp” 文件中添加代码如下:
#include <QGraphicsItemAnimation>
#include <QTimeLine>
#include "startitem.h"
其中,在createActionsO函数中添加代码如下:
addAnimItemAct = new QAction(tr(" 加入星星"), this);
connect(addAnimItemAct,SIGNAL(triggered()),this,SLOT(slotAddAnimationItem()));
在 createMenus() 函数中添加代码如下:
itemsMenu->addAction(addAnimItemAct);
在 initScene()函数中添加代码如下:
for(i=0;i<3;i++)
slotAddAnimationItem();
函数 slotAddAnimationItem()的具体实现代码如下:
void MainWindow::slotAddAnimationItem() //在场景中加入一个动画星星
{
StartItem *item= new StartItem;
QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
anim->setItem(item);
QTimeLine *timeLine = new QTimeLine(4000);
timeLine->setCurveShape(QTimeLine::SineCurve);
timeLine->setLoopCount(0);
anim->setTimeLine(timeLine);
int y =(qrand()%400)-200;
for(int i=0;i<400;i++)
{
anim->setPosAt(i/400.0,QPointF(i-200,y));
}
timeLine->start();
scene->addItem(item);
}
二、GraphicsItem V1.2 效果实例
图一
添加图片到Resources中步骤如下:
图二
三、原码解析
flashitem.h
#ifndef FLASHLTEM_H
#define FLASHLTEM_H
#include <QGraphicsItem>
#include <QPainter>
class FlashItem : public QObject,public QGraphicsItem
{
Q_OBJECT
public:
explicit FlashItem(QObject *parent = nullptr);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
void timerEvent(QTimerEvent *);
private:
bool flash;
QTimer *timer;
signals:
public slots:
};
#endif // FLASHLTEM_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMenuBar>
#include <QGraphicsEllipseItem>
#include <QDebug>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
void initScene(); //初始化场景
void createActions(); //创建主窗体的所有动作
void createMenus(); //创建主窗体的菜单栏
public slots:
void slotNew(); //新建一个显示窗体
void slotClear (); //清除场景中所有的图元
void slotAddEllipseItem(); //在场景中加入一个椭圆形图元
void slotAddPolygonItem (); //在场景中加入一个多边形图元
void slotAddTextItem(); //在场景中加入一个文字图元
void slotAddRectItem (); //在场景中加入一个长方形图元
void slotAddAlphaItem(); //在场景中加入一个透明蝴蝶图片
/*********************/
void slotAddFlashItem();
/*********************/
/*********************/
void slotAddAnimationItem();
/*********************/
private:
QGraphicsScene *scene;
QAction *newAct;
QAction *clearAct;
QAction *exitAct;
QAction *addEllipseItemAct;
QAction *addPolygonItemAct;
QAction *addTextItemAct;
QAction *addRectItemAct;
QAction *addAlphaItemAct;
/*********************/
QAction *addFlashItemAct;
/*********************/
/*********************/
QAction *addAnimItemAct;
/*********************/
};
#endif // MAINWINDOW_H
startitem.h
#ifndef STARTITEM_H
#define STARTITEM_H
#include <QGraphicsItem>
#include <QPainter>
class StartItem : public QGraphicsItem
{
public:
StartItem();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
private:
QPixmap pix;
};
#endif // STARTITEM_H
flashitem.cpp
#include "flashitem.h"
FlashItem::FlashItem(QObject *parent) : QObject(parent)
{
flash=true; //为颜色切换标识赋初值
setFlag(ItemIsMovable); //设置图元的属性, ItemIsMovable 表示此图元是可移动的,可 用鼠标进行拖曳操作。
startTimer(1000); ///启动一个定时器,以 1000 毫秒为时间间隔
}
/*定义图元边界的函数 boundingRect(), 完成以图元坐标系为基础,增加两个像素点的冗余工作。*/
QRectF FlashItem::boundingRect() const
{
qreal adjust= 2;
return QRectF(-10-adjust,-10-adjust,43+adjust,43+adjust);
}
/*自定义图元重绘的函数 paint()的具体实现代码如下*/
void FlashItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
painter->setPen(Qt::NoPen); //闪烁图元的阴影区不绘制边线
painter->setBrush (Qt:: darkGray); //闪烁图元的阴影区的阴影画刷颜色为深灰
painter->drawEllipse(-7,-7,40,40); //绘制阴影区
painter->setPen(QPen(Qt::black,0));
//闪烁区的椭圆边线颜色为黑色、线宽为 0
/*设置闪烁区的椭圆画刷颜色根据颜色切换标识 flash 决定在椭圆中填充哪种颜色,颜色在红色和黄色之间选择。*/
painter->setBrush(flash?(Qt::red):(Qt::yellow));
/*绘制与阴影区同样形状和大小的椭圆,并错开一定的距离以实现立体的感觉。*/
painter->drawEllipse( -10,-10,40,40); //(b)
}
/*定时器响应函数 timerEvent()完成颜色切换标识的反置,并在每次反置后调用 update()函数
重绘图元以实现闪烁的效果。*/
void FlashItem::timerEvent(QTimerEvent *)
{
flash=!flash;
update();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "flashitem.h"
#include <QGraphicsItemAnimation>
#include <QTimeLine>
#include "startitem.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createActions(); //创建主窗体的所有动作
createMenus(); //创建主窗体的菜单栏
scene = new QGraphicsScene;
scene->setSceneRect(-200,-200,400,400);
initScene (); //初始化场景
QGraphicsView *view= new QGraphicsView;
view->setScene(scene);
view->setMinimumSize(400,400);
view->show () ;
setCentralWidget(view);
resize(550,450);
setWindowTitle(tr("Graphics Items"));
}
MainWindow::~MainWindow()
{
}
void MainWindow::createActions() //创建主窗体的所有动作
{
newAct = new QAction(tr(" 新建 "),this);
clearAct = new QAction(tr(" 清除") , this) ;
exitAct = new QAction(tr(" 退出 "),this);
addEllipseItemAct = new QAction(tr("加入椭圆 "),this);
addPolygonItemAct = new QAction(tr("加入多边形 "),this);
addTextItemAct = new QAction(tr("加入文字 "),this);
addRectItemAct = new QAction(tr("加入长方形 "),this);
addAlphaItemAct= new QAction(tr("加入透明图片 "),this);
connect (newAct, SIGNAL (triggered()), this, SLOT (slotNew ()));
connect(clearAct,SIGNAL (triggered()), this, SLOT (slotClear ()));
connect (exitAct, SIGNAL (triggered()), this, SLOT (close()));
connect (addEllipseItemAct,SIGNAL(triggered()), this, SLOT(slotAddEllipseItem ()));
connect (addPolygonItemAct,SIGNAL(triggered()), this, SLOT(slotAddPolygonItem ())) ;
connect(addTextItemAct,SIGNAL(triggered()),this,SLOT(slotAddTextItem ())) ;
connect(addRectItemAct,SIGNAL(triggered()),this,SLOT(slotAddRectItem ()));
connect(addAlphaItemAct,SIGNAL(triggered()),this,SLOT(slotAddAlphaItem()));
/*******************************************/
addFlashItemAct = new QAction(tr("加入闪烁圆 "),this);
connect(addFlashItemAct,SIGNAL(triggered()),this,SLOT(slotAddFlashItem()));
addAnimItemAct = new QAction(tr(" 加入星星"), this);
connect(addAnimItemAct,SIGNAL(triggered()),this,SLOT(slotAddAnimationItem()));
}
void MainWindow::createMenus() //创建主窗体的菜单栏
{
QMenu *fileMenu = menuBar () ->addMenu (tr(" 文件")) ;
fileMenu->addAction(newAct);
fileMenu->addAction(clearAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
QMenu *itemsMenu = menuBar()->addMenu(tr(" 元素")) ;
itemsMenu->addAction(addEllipseItemAct);
itemsMenu->addAction(addPolygonItemAct);
itemsMenu->addAction(addTextItemAct);
itemsMenu->addAction(addRectItemAct);
itemsMenu->addAction(addAlphaItemAct);
/**********************************/
itemsMenu->addAction(addFlashItemAct);
itemsMenu->addAction(addAnimItemAct);
}
void MainWindow:: initScene () //初始化场景
{
int i;
for(i=0;i<3;i++)
slotAddEllipseItem ();
for(i=0;i<3;i++)
slotAddPolygonItem();
for(i=0;i<3;i++)
slotAddTextItem () ;
for(i=0;i<3;i++)
slotAddRectItem();
for(i=0;i<3;i++)
slotAddAlphaItem();
for(i=0;i<3;i++)
slotAddFlashItem();
for(i=0;i<3;i++)
slotAddAnimationItem();
}
void MainWindow::slotNew() //新建一个显示窗体
{
slotClear();
initScene();
MainWindow *newWin = new MainWindow;
newWin->show ();
}
void MainWindow::slotClear() //清除场景中所有的图元
{
QList<QGraphicsItem*>listItem = scene->items();
while (!listItem.empty())
{
scene->removeItem(listItem.at (0));
listItem.removeAt(0);
}
}
void MainWindow::slotAddEllipseItem() //在场景中加入一个椭圆形图元
{
QGraphicsEllipseItem *item= new QGraphicsEllipseItem(QRectF(0,0,80,60));
item->setPen (Qt::NoPen);
item->setBrush(QColor(qrand() %256,qrand() %256,qrand() %256));
item->setFlag(QGraphicsItem::ItemIsMovable);
scene->addItem(item);
item->setPos((qrand() %int (scene->sceneRect () . width())) -200,
(qrand () %int (scene->sceneRect () . height ())) -200);
}
void MainWindow::slotAddPolygonItem() //在场景中加入一个多边形图元
{
QVector<QPoint> v;
v<<QPoint(30,-15)<<QPoint(0,-30)<<QPoint(-30,-15)
<<QPoint(-30,15)<<QPoint(0,30)<<QPoint(30,15);
QGraphicsPolygonItem *item= new QGraphicsPolygonItem(QPolygonF(v));
item->setBrush (QColor(qrand()%256, qrand () %256, qrand ()%256));
item->setFlag(QGraphicsItem::ItemIsMovable);
scene->addItem(item);
item->setPos((qrand()%int (scene->sceneRect ().width()))-200,
(qrand() %int (scene->sceneRect().height())) -200);
}
void MainWindow::slotAddTextItem() //在场景中加入一个文字图元
{
QFont font("Times",16);
QGraphicsTextItem *item= new QGraphicsTextItem("Hello Qt");
item->setFont(font);
item->setFlag(QGraphicsItem::ItemIsMovable);
item->setDefaultTextColor(QColor(qrand()%256, qrand()%256, qrand ()%256));
scene->addItem(item);
item->setPos((qrand()%int (scene->sceneRect().width())) -200,
(qrand()%int(scene->sceneRect() .height ()))-200);
}
void MainWindow::slotAddRectItem() //在场景中加入一个长方形图元
{
QGraphicsRectItem *item= new QGraphicsRectItem(QRectF(0,0, 60,60));
QPen pen;
pen.setWidth(3);
pen. setColor(QColor(qrand()%256, qrand ()%256, qrand()%256));
item->setPen(pen);
item->setBrush (QColor (qrand()%256, qrand()%256, qrand()%256));
item->setFlag(QGraphicsItem::ItemIsMovable);
scene->addItem(item);
item->setPos ((qrand()%int (scene->sceneRect ().width())) -200,
(qrand()%int (scene->sceneRect ().height())) -200);
}
void MainWindow::slotAddAlphaItem() //在场景中加入一个皮卡丘图片
{
QGraphicsPixmapItem *item=scene->addPixmap(QPixmap(":/src/piKa.png"));
item->setFlag(QGraphicsItem::ItemIsMovable);
item->setPos ((qrand ()%int (scene->sceneRect ().width())) -200,
(qrand() %int (scene->sceneRect () . height())) -200) ;
}
void MainWindow::slotAddFlashItem() //在场景中加入一个闪烁图元
{
FlashItem *item= new FlashItem;
scene->addItem (item);
item->setPos ((qrand()%int (scene->sceneRect () . width())) -200,
(qrand()%int (scene->sceneRect ().height())) -200);
}
void MainWindow::slotAddAnimationItem() //在场景中加入一个动画星星
{
StartItem *item= new StartItem;
QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
anim->setItem(item);
QTimeLine *timeLine = new QTimeLine(4000);
timeLine->setCurveShape(QTimeLine::SineCurve);
timeLine->setLoopCount(0);
anim->setTimeLine(timeLine);
int y =(qrand()%400)-200;
for(int i=0;i<400;i++)
{
anim->setPosAt(i/400.0,QPointF(i-200,y));
}
timeLine->start();
scene->addItem(item);
}
startitem.cpp
#include "startitem.h"
/*在 Startltem()构造函数中仅完成读取图片信息的工作。*/
StartItem::StartItem()
{
pix.load(":/src/star.png");
}
/*定义图元的边界函数 boundingRect(), 它是所有自定义图元均必须实现的函数*/
QRectF StartItem::boundingRect()const
{
return QRectF (-pix. width() / 2, -pix. height() /2,pix.width () ,pix. height()) ;
}
/*自定义图元重绘函数 paint()*/
void StartItem::paint (QPainter *painter, const QStyleOptionGraphicsItem*option,QWidget *widget)
{
painter->drawPixmap(boundingRect().topLeft(),pix);
}
四、总结
图元创建会在应用程序开发中经常用到的